Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Issue using .dll in Program vs Service

Issue using .dll in Program vs Service

Scheduled Pinned Locked Moved C#
visual-studiohelp
6 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    abupsman
    wrote on last edited by
    #1

    I need some assistance in tracking down why my code will not run as a service. I have been hacking at this for over two weeks on and off with no real progress. I need to use an old dll to access data. When I call it from a console app, it works just fine. Here is a snip of the code that works... [DllImport("C:\\Program Files\\Omaha_Steaks_NUCAS_Reader\\libhab2.dll")] public static extern int HABRSCI(string RSCI1, string RSCI2, string RSCI3, string RSCI4, string RSCI5); static void Main() { try { //Create Variables for Host Access string string resbuff = new string(' ', 80); string reascode = "0000"; HABRSCI("0000", "01", "nucas.txt\0", resbuff, reascode); } catch (Exception ex) { string zzzz = ex.Message; } } I rewrote as a Service, everything works except the dll call, it just acts as it was never called at all. Here are some snips from my Service code.... //Set up usage of the .dll for Host Access [DllImport("C:\\Program Files\\OS_NUCAS_Reader\\libhab2.dll",EntryPoint = "HABRSCI")] public static extern int HABRSCI(string RSCI1, string RSCI2, string RSCI3, string RSCI4, string RSCI5); and later, inside of a timer event.. try { //Create Variables for Host Access string string resbuff = new string(' ', 80); string reascode = "0000"; HABRSCI("0000", "01", "nucas.txt\0", resbuff, reascode); } catch (Exception ex) { } This is just ignored!!! I know the code executes around it, I have even added lines to write to the Event log just before and after the call. If it works, a text file is created and a records is added to a log file maintained by the dll. none of these are happening so it apears that it ignores the call to the dll when running as Service. Any assistance would be much appreciated. Thanks, Don

    L 1 Reply Last reply
    0
    • A abupsman

      I need some assistance in tracking down why my code will not run as a service. I have been hacking at this for over two weeks on and off with no real progress. I need to use an old dll to access data. When I call it from a console app, it works just fine. Here is a snip of the code that works... [DllImport("C:\\Program Files\\Omaha_Steaks_NUCAS_Reader\\libhab2.dll")] public static extern int HABRSCI(string RSCI1, string RSCI2, string RSCI3, string RSCI4, string RSCI5); static void Main() { try { //Create Variables for Host Access string string resbuff = new string(' ', 80); string reascode = "0000"; HABRSCI("0000", "01", "nucas.txt\0", resbuff, reascode); } catch (Exception ex) { string zzzz = ex.Message; } } I rewrote as a Service, everything works except the dll call, it just acts as it was never called at all. Here are some snips from my Service code.... //Set up usage of the .dll for Host Access [DllImport("C:\\Program Files\\OS_NUCAS_Reader\\libhab2.dll",EntryPoint = "HABRSCI")] public static extern int HABRSCI(string RSCI1, string RSCI2, string RSCI3, string RSCI4, string RSCI5); and later, inside of a timer event.. try { //Create Variables for Host Access string string resbuff = new string(' ', 80); string reascode = "0000"; HABRSCI("0000", "01", "nucas.txt\0", resbuff, reascode); } catch (Exception ex) { } This is just ignored!!! I know the code executes around it, I have even added lines to write to the Event log just before and after the call. If it works, a text file is created and a records is added to a log file maintained by the dll. none of these are happening so it apears that it ignores the call to the dll when running as Service. Any assistance would be much appreciated. Thanks, Don

      L Offline
      L Offline
      Luc Pattyn
      wrote on last edited by
      #2

      Hi, I suggest you gather all information to find out what goes wrong, so: 1. make sure you create a log file, and append all significant progress/trace info to it, one line at a time. 2. don't ignore exceptions catch (Exception ex) {string zzzz = ex.Message;} and catch (Exception ex) {} don't make sense since you are not doing anything with the exception's information. Furthermore, you should always use Exception.ToString() keeping all the details. 3. Make sure your app has an overall try-catch on top of your regular exception processing, so even if you miss a local exception, you still catch it at the top level. You should apply this to your main thread (the static main method), as to every thread you create. 4. check and log all return values public static extern int HABRSCI(...) promises a result, so store it in an int and look at it. Maybe it is a status, with some negative value indicating a specific error. 5. don't trust defaults for P/Invoke; I don't care to remember what calling convention is used, I specify it explicitly on both sides (managed and unmanaged); example: [DllImport("Winmm.dll", CallingConvention=CallingConvention.StdCall)] static extern int sndPlaySound(IntPtr buffer, int dwFlags); Hope this helps.

      Luc Pattyn [Forum Guidelines] [My Articles]


      This month's tips: - before you ask a question here, search CodeProject, then Google; - the quality and detail of your question reflects on the effectiveness of the help you are likely to get; - use PRE tags to preserve formatting when showing multi-line code snippets.


      A 1 Reply Last reply
      0
      • L Luc Pattyn

        Hi, I suggest you gather all information to find out what goes wrong, so: 1. make sure you create a log file, and append all significant progress/trace info to it, one line at a time. 2. don't ignore exceptions catch (Exception ex) {string zzzz = ex.Message;} and catch (Exception ex) {} don't make sense since you are not doing anything with the exception's information. Furthermore, you should always use Exception.ToString() keeping all the details. 3. Make sure your app has an overall try-catch on top of your regular exception processing, so even if you miss a local exception, you still catch it at the top level. You should apply this to your main thread (the static main method), as to every thread you create. 4. check and log all return values public static extern int HABRSCI(...) promises a result, so store it in an int and look at it. Maybe it is a status, with some negative value indicating a specific error. 5. don't trust defaults for P/Invoke; I don't care to remember what calling convention is used, I specify it explicitly on both sides (managed and unmanaged); example: [DllImport("Winmm.dll", CallingConvention=CallingConvention.StdCall)] static extern int sndPlaySound(IntPtr buffer, int dwFlags); Hope this helps.

        Luc Pattyn [Forum Guidelines] [My Articles]


        This month's tips: - before you ask a question here, search CodeProject, then Google; - the quality and detail of your question reflects on the effectiveness of the help you are likely to get; - use PRE tags to preserve formatting when showing multi-line code snippets.


        A Offline
        A Offline
        abupsman
        wrote on last edited by
        #3

        Luc Good suggestions all. I may have edited out too much when posting the code... Anyway, I have run this with lines just before and after the HABRSCI call logging to an eventlog so I know it is getting to this line. As to exceptions, they never come into play, no errors are happening (I have logging events in those sections also, never happen) I can watch the app run by monitoring the lines being added to the event log, it loops every three minutes (current setting) and does several things, but the .dll never responds. I did test it by adding code to return an int, but that always stays at zero in the Service (= no result) but returns either 4,8, or 16 in the Console version (indicates type of response collected by .dll) If the .dll works, it generates a small text file with result data AND adds a 65 char line record to a text file in the local folder with status and timestamp information. This happens in the console version but not in the service version. I will try the explicit call in #5 above to see if that helps. Thanks, Don :)

        L 1 Reply Last reply
        0
        • A abupsman

          Luc Good suggestions all. I may have edited out too much when posting the code... Anyway, I have run this with lines just before and after the HABRSCI call logging to an eventlog so I know it is getting to this line. As to exceptions, they never come into play, no errors are happening (I have logging events in those sections also, never happen) I can watch the app run by monitoring the lines being added to the event log, it loops every three minutes (current setting) and does several things, but the .dll never responds. I did test it by adding code to return an int, but that always stays at zero in the Service (= no result) but returns either 4,8, or 16 in the Console version (indicates type of response collected by .dll) If the .dll works, it generates a small text file with result data AND adds a 65 char line record to a text file in the local folder with status and timestamp information. This happens in the console version but not in the service version. I will try the explicit call in #5 above to see if that helps. Thanks, Don :)

          L Offline
          L Offline
          Luc Pattyn
          wrote on last edited by
          #4

          Hi Don, some more ideas: 1. if you have the source of the unmanaged code, you can add logging there too. what I typically do is make it such that the unmanaged code logs to the managed world, using a delegate (which becomes a function pointer). 2. if the DLL has a simpler function somewhere, try that one first; or if you have the source, add a simple function and try it (e.g. something that takes two ints and returns the product). Success here proves you are accessing the DLL, and doing some P/Invoke correctly. 3. I was a little surprised by the explicit NULL char in one of the args; if you try to get a double NULL to the unmanaged world, I am not sure the marshaling will do that for you. 4. if the unmanaged code throws an exception, it might just kill the thread without you noticing (depending on which timer you use, you may get a separate thread). You said "as if the function was not called", does the code return well from the unmanaged function, i.e. does the next (log) line get executed? 5. If everything else fails my best guess is the unmanaged code executes but fails maybe because there is no user, hence no "My Documents" and the like. Good error trapping should catch that. :)

          Luc Pattyn [Forum Guidelines] [My Articles]


          This month's tips: - before you ask a question here, search CodeProject, then Google; - the quality and detail of your question reflects on the effectiveness of the help you are likely to get; - use PRE tags to preserve formatting when showing multi-line code snippets.


          A 1 Reply Last reply
          0
          • L Luc Pattyn

            Hi Don, some more ideas: 1. if you have the source of the unmanaged code, you can add logging there too. what I typically do is make it such that the unmanaged code logs to the managed world, using a delegate (which becomes a function pointer). 2. if the DLL has a simpler function somewhere, try that one first; or if you have the source, add a simple function and try it (e.g. something that takes two ints and returns the product). Success here proves you are accessing the DLL, and doing some P/Invoke correctly. 3. I was a little surprised by the explicit NULL char in one of the args; if you try to get a double NULL to the unmanaged world, I am not sure the marshaling will do that for you. 4. if the unmanaged code throws an exception, it might just kill the thread without you noticing (depending on which timer you use, you may get a separate thread). You said "as if the function was not called", does the code return well from the unmanaged function, i.e. does the next (log) line get executed? 5. If everything else fails my best guess is the unmanaged code executes but fails maybe because there is no user, hence no "My Documents" and the like. Good error trapping should catch that. :)

            Luc Pattyn [Forum Guidelines] [My Articles]


            This month's tips: - before you ask a question here, search CodeProject, then Google; - the quality and detail of your question reflects on the effectiveness of the help you are likely to get; - use PRE tags to preserve formatting when showing multi-line code snippets.


            A Offline
            A Offline
            abupsman
            wrote on last edited by
            #5

            Luc, Thanks for sparking an idea that did fix prt of the problem. Your #5 comment did the trick (the "My Documents" bit!) It appears that while it is running as a console app, any file calls are, unless otherwise directed, sent to the folder where the .exe file is. In my case, to make this old .dll work, there MUST be a .cfg configuration file AND a file name reference .txt file in the same folder as the libhab2.dll. As an console app, those were placed there by the installer. I guess I assumed that this was the case with a Service also. NOT.....! All calls are sent to the C:\WINNT\System32 folder. I placed copies of the .cfg and .txt (the .dll was alredy there) in there and it works! Now I just have to figure how to redirect the "local" folder of a system login. (I guess I could leave the files in system32 but that feels wrong somehow!) Error trapping did not help because the .dll just returned with a Zero and no other information. It had been writing to it's own log file, but I did not see it because I was expecting to to be created and added to in the C:\Program Files\OSNUCASReader folder, not C:\WINNT\System32. If I had done a global search of my HD looking for "hafelog.log", I would have saved a week of hairpulling! The log only had a line like this: "20080116115428 23KDGWDLOG F_Dialog e 00085370Internal processing error encountered during routine operations. " BUT, it would have let me know that the .dll was being called. I just was not thinking about the System32 folder (too many trees to see the forest I guess) Anyway, thanks for the suggestions and the spark to get me moving forward. Don :-D

            L 1 Reply Last reply
            0
            • A abupsman

              Luc, Thanks for sparking an idea that did fix prt of the problem. Your #5 comment did the trick (the "My Documents" bit!) It appears that while it is running as a console app, any file calls are, unless otherwise directed, sent to the folder where the .exe file is. In my case, to make this old .dll work, there MUST be a .cfg configuration file AND a file name reference .txt file in the same folder as the libhab2.dll. As an console app, those were placed there by the installer. I guess I assumed that this was the case with a Service also. NOT.....! All calls are sent to the C:\WINNT\System32 folder. I placed copies of the .cfg and .txt (the .dll was alredy there) in there and it works! Now I just have to figure how to redirect the "local" folder of a system login. (I guess I could leave the files in system32 but that feels wrong somehow!) Error trapping did not help because the .dll just returned with a Zero and no other information. It had been writing to it's own log file, but I did not see it because I was expecting to to be created and added to in the C:\Program Files\OSNUCASReader folder, not C:\WINNT\System32. If I had done a global search of my HD looking for "hafelog.log", I would have saved a week of hairpulling! The log only had a line like this: "20080116115428 23KDGWDLOG F_Dialog e 00085370Internal processing error encountered during routine operations. " BUT, it would have let me know that the .dll was being called. I just was not thinking about the System32 folder (too many trees to see the forest I guess) Anyway, thanks for the suggestions and the spark to get me moving forward. Don :-D

              L Offline
              L Offline
              Luc Pattyn
              wrote on last edited by
              #6

              Hi Don, glad to be able to help. yeah, I don't hesitate searching the whole C: drive for a file...; all too often something gets stored in strange places.

              Member 4372837 wrote:

              "20080116115428 23KDGWDLOG F_Dialog e 00085370Internal processing error encountered during routine operations. "

              not the most useful message... :)

              Luc Pattyn [Forum Guidelines] [My Articles]


              This month's tips: - before you ask a question here, search CodeProject, then Google; - the quality and detail of your question reflects on the effectiveness of the help you are likely to get; - use PRE tags to preserve formatting when showing multi-line code snippets.


              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups