Click here to Skip to main content
15,884,084 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello,
I work for some time with COM and especially with ATL template classes, but I am not an expert so please be patient with me if this is a stupid question.

I now want to create a singleton COM Object which is hostet by a windows service. I decide to use a service cause it can run under system account.

Here are my steps in detail:
1. Create an ATL project("ATLService.exe") as a service(.exe) with VS2010 SP1.
2. Add an ATL Simple Object to the project, also add the ProgId"ATLService.ComObject" to the wizzard.
3. Change the *.rgs of the ATLService to get the entry in dcomcnfg like:
C++
NoRemove AppID
   {
       '%APPID%' = s 'ATLService'
       'ATLService.EXE'
       {
           val AppID = s '%APPID%'
       }
   }

4.Compile the project an register with /Service, so the ComObject can be found in the registry and the ATLServcie can be found in services.msc and in dcomcnfg
5. Add the user to the Launch, Access und Activation permission of the service in dcomcnfg settings.
6. Identity of the service is system account
7. start service in service.msc
8. Start a client to create an instance of ATLService.ComObject.1 like this:
C++
wchar_t wszProg[] = {L"ATLService.ComObject.1"};
CLSID clsid;
HRESULT hr = CLSIDFromProgID(wszProg,&clsid);

CComPtr<IUnknown> pUnk;
hr = ::CoCreateInstance(clsid,NULL,CLSCTX_LOCAL_SERVER,
                        IID_IUnknown,(void**)&pUnk);

For CoCreateInstance i got the 0x80080005 server execution failed message. It is really frustrating. If I change the register from /service to /regserver it works well. What could be the reason?
Posted

The normal use of regsvr32 on the command line (as admin) is:

regsvr32 FILENAME (PARAMETERS)

The Parameters are optional and get input for the executed file in which the function DllRegisterServer is called. You can set a breakpoint in your binary and debug. Really!!!

Some further explanation (I found) is in this article.
 
Share this answer
 
Comments
mallews 19-Mar-15 17:36pm    
Hello KarstenK,
thank you for your answer. But I think regsvr32 is used to register Com Objects hostet by a dll. The regsvr32.exe loads the library and calls the exported functions eg. DllRegisterServer or DllUnregister Server. I think this is not the same procedure for outproc Servers. They do not really can export those functions therefore it is startet with arguments like /RegServer or /UnregServer. In the main function this arguments are checked and call then equal Methods.

Maybe I am wrong and the service is not used to host Com Object could this be?
The entry points for Services and Local Servers are slightly different - there is a member bool (m_bService)you can query to determine how you're running

Given that you can execute the thing as a local Server, your COM glue is all working - there's probably some element that you don't handle well when run as a service

By far the easiest thing to do in these cases is to add the following at the start of your Run() method (after you RegisterServer(true))

C++
#ifdef _DEBUG
        if(m_bService)
        {
            // remember to enable Interact With Desktop if you turn this msgbox on, and watch for station/desktop changes in >=win7
            //MessageBox(_T("attach"),_T("attach"),MB_OK);
            Sleep(15000);
            // F9 on this line
            int debug=1;
        }
#endif


Register this service again, run your client (or a testharness) and attach to the service in the 15 second window

you'll probably find that your service is either exploding or falling straight out of the PreMessageLoop because it doesn't like your parameters in your call to CoInitializeSecurity inside your InitializeSecurity
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900