Link to home
Start Free TrialLog in
Avatar of ZANTAR
ZANTAR

asked on

A C++ service keeping a VB object alive after the user has logged off

Hello,

I have a Visual C++ service that is using an ActiveX Exe (Similar to an ActiveX Dll). The service needs to run the following code and create an instance of a connector object from the Active exe. This code is currently working 100%.

The problem:
If the user starts the service, which calls the RUN command, the connector object gets created correctly. However, if the user logs off the machine while the service is running, the connector object is killed and the service continues to operate. My guess is that I need to specify the Windows NT login when creating the connector object. So if the service is started up by USER1, and the machine is logged in as USER2, the connector object will belong to USER1. That way if the USER2, logs off, the service and connector object still exist.

A couple of ideas that might be part of the solution:
-     CREATEPROCESS()?
-     COCREATEINSTANCE()?

Here is the procedure that creates the connector object in C++.

// I have removed the catch code and I only am showing the try code.

void MyApp::CMyAppService::Run()
{
   long iLoopCount;  //a loop  counter  
   long iRetryCount; //a retry counter  
   long iStart;   //a Return Code for Start MyServer
   long iRefresh; //a Return Code for Refresh MyServer
   long iStop;
   std::wstring aMsg;
   std::wstring aPrtMsg;

    HRESULT hr;    //a Return Code of COM

   //The following code is to call a VB ActiveX Exe
   CoInitialize(NULL);                             //open a COM thread
               
   _ConnectorPtr aConnector;                       //a smart point to the VB object
   hr = aConnector.CreateInstance(__uuidof(Connector)); //create an instance of a connector object
         
   // Check the status of ?hr? here to ensure that the connector was created

   //Start the MyServer
   iStart=(long)aConnector->ConnStartMyServer();
}

I have lots of experience with VB and RDBMS, but I only have 1 year of C++ knowledge. If your solution requires many steps, please document clearly, as it will help immensely.

Thank you very much for your time,

Dave Hall

Avatar of Thangs
Thangs

Is it possible to stop the server explicitly. So that when you stop the conenctor, it stops the server also. Try to release the server explicitly.

This may works out for you.

Thangs
Avatar of ZANTAR

ASKER

If the user logs off the machine, I want the connector object and the services to continue to run. I have other services which run no problem if the user is not logged on.
Avatar of ZANTAR

ASKER

I need a solution quickly as possible.
1.If the activeX control also developed by yourself, you can change it to a Service.
2.Use RegisterServiceProcess register your ActiveX Exe as service.
i.e.
// ....
_ConnectorPtr aConnector;                       //a smart point to the VB object
  hr = aConnector.CreateInstance(__uuidof(Connector)); //create an instance of a connector object
// Now you can register the ActiveX exe server as a service.
// so it will not be close when log off
....
RegisterServiceProcess(...);        
//...
 
ASKER CERTIFIED SOLUTION
Avatar of BeyondWu
BeyondWu
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ZANTAR

ASKER

BeyondWu,

Both the Visual C++ service and the Visual Basic ActiveX Exe have been written by myself. With that in mind, which solution would you recommend to implement?

The "Connector" is a VB class that belongs to the ActiveX Exe and needs to be created from the VC++ service and kept alive even after the user logs off.

I have seen CreateProcess used to startup applications (.exe) from with C++ code. However, how do you ensure that if the user logs off the machine, that the process is not killed? Or is this not a concern?

Thanks for the feedback and I will attempt to try both solutions.
Avatar of ZANTAR

ASKER

Also,

If this helps.... The current code does an import in the header file so that the createinstance code does not need the GUID, because the import gets it automatically. So if I try using the createprocess, should I then get rid of the import?

#import "MyServer.exe" no_namespace //import the interface of ActiveX MyServer.Exe
Run the aervice on LOcal System Account (this is default), but on "This user account"
Avatar of ZANTAR

ASKER

The service must run on the domain account and under a different user account than that which is logging on/off to start up the service.

If the machine reboots, the service will startup automatically even if the user does not start up the service. This is already implemented.
ZANTAR:
If you develop under win9x, you can use RegisterServiceProcess to register your activex component as a service, but you can't use it on Win2K or NT.
Maybe you can use OpenSCManager to install it, but i don't ensure.

If your activex is not very complex, I recommend you change to use VC/ATL wizard to convert it to a service.
I think it's the easiest way.
Avatar of ZANTAR

ASKER

The VB ActiveX exe is very complex and does tons of calculations and database calls. It currently runs on Win NT and after searching on the web about using RegisterServiceProcess in VB. I found out that RegisterServiceProcess does not exist in Kernel32 for Win Nt.

I can't use RegisterServiceProcess on NT (not in VC++ or VB). But, can I use CreateProcess to start up the VB ActiveX exe using the same user account that the VC++ service was started up by? Then create the instance of the connector object?
I'm not very familiar VB,
Do you know is there some options that can create your component as a service in VB?
Do you can change your component to DLL?
And I don't ensure if the CreateProcess can help you.
Avatar of ZANTAR

ASKER

Avatar of ZANTAR

ASKER

Avatar of ZANTAR

ASKER

Unfortunately, the ActiveX exe must remain as one, because it acts as an OLE SERVER between the client software and the service.

Is there anyway to startup the ActiveX exe using createprocess?
Avatar of ZANTAR

ASKER

When I'm asking about using CreateProcess, I mean startup the ActiveX exe using CreateProcess from in C++
Avatar of ZANTAR

ASKER

I just want to thank you for your help. The final solution was that I didn't need to do anything with the C++ or VB active X exe. It turned out that the DCOM configuration was the problem. I needed to setup the service and the VB active X exe to use a specific user account rather than letting it decide which to use.

However, I found a lot of useful things to do with createprocess and registerserviceprocess functions.

Thanks and Congratulations!
Can you tell me the detail how you resolve your problem?
Thanks!
Avatar of ZANTAR

ASKER

Here are the steps:

1. Click Start-> Settings -> Control Panel
2. Open Services
3. Scroll down to "MyService" and highlight it.
4. Ensure that it is STOPPED.
5. Select the startup button
6. In the "Log on as" frame, Select "This account" and enter the following:

     This Account: <Enter the Domain>\SharedServiceAccount
     Password: <Enter SharedServiceAccount password here, case sensitive>
     Confirm Password: <Enter SharedServiceAccount password here, case sensitive>

7. In the "Startup Type" frame, Select "Automatic". This way when the computer starts, so will start the service when the machine fails.
8. Click Ok to save the changes
9. Click Close, to close the services window.
10. Click Start->Run
11. Enter "dcomcnfg" and OK
12. Click the "Default Security" tab.
13. Ensure that Domain users have "Allow Access" under "Access permissions" by clicking "Edit default" permissions.
14. Ensure that Domain users have "Allow Launch" under "Launch permissions" by clicking "Edit default" permissions.
15. Under the "Applications" tab, scroll down to "MyActiveXexe.xxxxx" and highlight it.
16. Click the "Properties..." button
17. Under the "General" tab, Authentication level should be "Connect"
18. Under the "Location" tab, only "Run on this computer" should be checked.
19. Under the "Security" tab, confirm the following:

     Use default access permissions, is selected.
     Use default launch permissions, is selected.
     Use custom configuration permissions, is selected.

20. Under the "Identity" tab, select "This user" and ener the following:

     User: <Enter the Domain>\SharedServiceAccount
     Password: <Enter SharedServiceAccount password here, case sensitive>
     Confirm Password: <Enter SharedServiceAccount password here, case sensitive>

21. Click OK to save the DCOM changes of the MyActiveXexe.xxxx .
22. Click OK to close the "Distributed COM Configuration"
23. Click Start-> Settings -> Control Panel
24. Scroll down to "MyService" and highlight it.
25. Click the "Start" button, to start the service.

Next, on ALL client computers where the client VB software is installed, do the following:

Note: The following steps do not need to be done on the computer with the MyService, as they have already been performed.

1. Click Start->Run
2. Enter "dcomcnfg" and OK
3. Click the "Default Security" tab.
4. Ensure that Domain users have "Allow Access" under "Access permissions" by clicking "Edit default" permissions.
5. Ensure that Domain users have "Allow Launch" under "Launch permissions" by clicking "Edit default" permissions.
6. Under the "Applications" tab, scroll down to "MyActiveXexe.xxxxx" and highlight it.
7. Click the "Properties..." button
8. Under the "General" tab, Authentication level should be "Connect"
9. Under the "Location" tab, only "Run on this computer" should be checked.
10. Under the "Security" tab, confirm the following:

     Use default access permissions, is selected.
     Use default launch permissions, is selected.
     Use custom configuration permissions, is selected.

11. Under the "Identity" tab, select "This user" and ener the following:

     User: <Enter the Domain>\SharedServiceAccount
     Password: <Enter SharedServiceAccount password here, case sensitive>
     Confirm Password: <Enter SharedServiceAccount password here, case sensitive>

12. Click OK to save the DCOM changes of the MyActiveXexe.xxxx .
13. Click OK to close the "Distributed COM Configuration"
14. Now startup the client VB software and point to the server running the MyService. It will now connect successfully.