2

Background:

I have used developed an OPC server based on LightOPC (https://github.com/Sayen/LightOPC). This works perfectly fine as a local executable. The only problem is that I want multiple clients to connect to the same instance of the exe so they can share data. Currently, even if the DCOM settings are such that it runs as a specific user, it seems that sometimes multiple instances of the exe start. The only solution has been to set it to run as the Interactive User. However this has an issue where it won't run if no user is logged in. I believe the right way is to make it run as a windows service.

Question:

How can I take my DCOM local executable and make it into a service?

Things I tried:

Based off of this question: Create Windows service from executable I used the NSSM( the non-Sucking Service Manager ) to make my exe into a service name MYOPCSERVICE.

Then based on some other googling and examining other OPC servers that run as services, I modified the following registry key:

HKEY_LOCAL_MACHINE\SOFTWARE\Classes\WOW6432Node\AppID{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} (where X's are my AppId) and added a "Local Service" key with the value of "MYOPCSERVICE".

After doing this, when I used DCOMCNFG, my DCOM Application shows up as Application Type = Local Service.

However, after adding this registry key, when I try to start the service or connect to the OPC server, the service fails to start with "CoRegisterClassObject() failed. Exiting..."

I found this document: https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-coregisterclassobject which has the following:

As of Windows Server 2003, if a COM object application is registered as a service, COM verifies the registration. COM makes sure the process ID of the service, in the service control manager (SCM), matches the process ID of the registering process. If not, COM fails the registration. If the COM object application runs in the system account with no registry key, COM treats the objects application identity as Launching User.

I don't know if this is the issue, and I also don't really understand what it means. What is the "process ID" being referred to? Is this the 1-4 digit integer that all Windows processes have? Or is this the name of the service and does it have to match the name of the executable or the class or the AppId?

Update:

I have been experimenting more, and I am starting to get the feeling that it isn't possible to use NSSM to make the COM executable into a service. It seems like the exe of the service needs to be the one that calls CoRegisterClassObject. I have made a simple service based off of Simple Windows Service in c++ https://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=499465 and when I do so, I can successfully call CoRegisterClassObject with the AppId of {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} if this AppId registry key contains the string LocalService = MYOPCSERVICE.

I think Windows is enforcing a rule that only the exe registered as a service (which is nssm.exe) is allowed to call CoRegisterClassObject. However nssm spawns another exe (the local OPC executable) and it doesn't pass along this ability. Does this sound accurate? Is there any work around besides having to write all my own service handlers?

bruceceng
  • 1,844
  • 18
  • 23

0 Answers0