windows服务windows xp启动失败败-Smite(游戏)

玩转Windows服务系列——无COM接口Windows服务启动失败原因及解决方案
将VS创建的Windows服务项目编译生成的程序,通过命令行 “服务.exe -Service”注册为Windows服务后,就可以通过服务管理器进行管理了。
通过服务管理器进行启动的时候,发现服务无法启动,提示错误
由于程序代码是由VS的项目模板生成的,生成后直接编译为Debug版,然后通过命令行进行注册,期间并没有修改过任何代码。
难道是只有Release版本才能通过服务管理器启动吗。于是将Release版注册为服务,通过服务管理器启动,仍然会报同样的错误。
由于服务比较特殊,应该会在Windows的事件管理器中留下日志,经查看,日志为
可以看到系统日志中并无异常。
问题还不只如此,当Debug版本通过 RegServer 注册后,程序也是启动后立即停止。
既然如此,那就开始使用神器——单步调试。
启动失败原因
Window服务程序启动后,会在WinMain方法中调用一个Run方法
HRESULT Run(_In_
int nShowCmd = SW_HIDE)
(){ HRESULT hr =
S_OK; T* pT = static_cast&T*&(
); hr = pT-&
PreMessageLoop(nShowCmd);
Call RunMessageLoop only if PreMessageLoop returns S_OK.
S_OK) { pT-&
RunMessageLoop(); }
Call PostMessageLoop if PreMessageLoop returns success.
(SUCCEEDED(hr)) { hr = pT-&
PostMessageLoop(); } ATLASSERT(SUCCEEDED(hr));
而Run方法中会调用pT-&RunMessageLoop()方法,来进行一个While循环,从而阻止WinMain方法返回,造成程序结束。
经过调试,发现执行时,pT-&PreMessageLoop 方法返回了S_FALSE,由于RunMessageLoop方法前有一个判断,所以此方法没有执行,从而造成程序启动便立即停止。
而真正造成PreMessageLoop方法返回S_FALSE的原因是
hr = pT-&RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED);
调用RegisterClassObjects方法,返回了S_FALSE,而RegisterClassObjects方法又调用了AtlComModuleRegisterClassObjects方法,实际上是在注册Com相关的东西,而由于程序是由VS创建的默认代码编译的,并未添加任何Com接口,所以就会返回S_FALSE,即注册失败。
找到了问题的原因了,那么也就相对好解决了。
既然程序中,并没有使用到Com相关的东西,那么就干脆跳过RegisterClassObjects方法的调用。
由于PreMessageLoop方法中通过宏_ATL_NO_COM_SUPPORT,可以决定是否跳过RegisterClassObjects的调用,所以只需要在预处理器中或者代码中定义这个宏即可。
#define _ATL_NO_COM_SUPPORT
或者通过预处理器来定义
原文链接:}

我要回帖

更多关于 windows7启动失败 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信