如何在ATL服务中创建COM对象hostet? [英] How do I create COM Objects hostet in a ATL Service?

查看:84
本文介绍了如何在ATL服务中创建COM对象hostet?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,

我和COM工作了一段时间,尤其是ATL模板课程,但我不是专家,所以如果这是一个愚蠢的问题,请耐心等待。



我现在想创建一个单独的COM对象,它是由windows服务提供的。我决定使用服务,因为它可以在系统帐户下运行。



以下是我的详细步骤:

1.创建一个ATL项目(ATLService.exe)作为服务(.exe)与VS2010 SP1。

2.向项目添加ATL简单对象,同时将ProgIdATLService.ComObject添加到wizzard 。

3.更改ATLService的* .rgs以获取dcomcnfg中的条目,如:

 NoRemove AppID 
{
' %APPID%' = s ' ATLService'
' ATLService .EXE'
{
val AppID = s ' %APPID%'
}
}



4.使用/ Service将项目编译成一个寄存器,以便可以找到ComObject注册表和ATLSer vcie可以在services.msc和dcomcnfg中找到

5.在dcomcnfg设置中将用户添加到服务的启动,访问和激活权限。

6.身份该服务是系统帐户

7.在服务中启动服务.msc

8.启动客户端以创建ATLService.ComObject.1实例,如下所示:

  wchar_t  wszProg [] = {L   ATLService.ComObject.1}; 
CLSID clsid;
HRESULT hr = CLSIDFromProgID(wszProg,& clsid);

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



对于CoCreateInstance,我得到了0x80080005服务器执行失败消息。真的很令人沮丧。如果我将/ service中的寄存器更改为/ regserver,则效果很好。可能是什么原因?

解决方案

命令行(作为管理员)正常使用regsvr32是:



regsvr32 FILENAME(参数)



参数是可选的,并获取调用函数DllRegisterServer的执行文件的输入。您可以在二进制文件中设置断点并进行调试。真的!!!



一些进一步的解释(我发现)就在这个文章


服务和本地服务器的入口点略有不同 - 有一个成员bool( m_bService )您可以查询以确定您的运行方式



鉴于您可以将该事物作为本地服务器执行,你的COM胶水全部工作 - 可能有一些你作为服务运行时处理不好的元素



到目前为止,在这些情况下最容易做的事情是在 Run()方法的开头添加以下内容(在 RegisterServer(true)之后)



  #ifdef _DEBUG 
if (m_bService)
{
// 如果您打开此msgbox,请记得启用Interact With Desktop,并在> = win7 中查看工作站/桌面更改
/ / MessageBox(_T(attach),_ T(attach),MB_OK);
Sleep( 15000 );
// 此行中的F9
int debug = 1 ;
}
#endif





注册此再次服务,运行您的客户端(或测试线)并在15秒窗口附加到服务



您可能会发现您的服务爆炸或下降直接退出 PreMessageLoop ,因为它不喜欢你的中的 CoInitializeSecurity 中的参数C> InitializeSecurity


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:

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:

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?

解决方案

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.


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))

#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


这篇关于如何在ATL服务中创建COM对象hostet?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆