玩转Windows服务系列——无COM接口Windows服务启动失败原因及解决方案

简介: 原文:玩转Windows服务系列——无COM接口Windows服务启动失败原因及解决方案将VS创建的Windows服务项目编译生成的程序,通过命令行 “服务.exe -Service”注册为Windows服务后,就可以通过服务管理器进行管理了。
原文: 玩转Windows服务系列——无COM接口Windows服务启动失败原因及解决方案

将VS创建的Windows服务项目编译生成的程序,通过命令行 “服务.exe -Service”注册为Windows服务后,就可以通过服务管理器进行管理了。

问题

通过服务管理器进行启动的时候,发现服务无法启动,提示错误

无Com接口服务启动失败

由于程序代码是由VS的项目模板生成的,生成后直接编译为Debug版,然后通过命令行进行注册,期间并没有修改过任何代码。

难道是只有Release版本才能通过服务管理器启动吗。于是将Release版注册为服务,通过服务管理器启动,仍然会报同样的错误。

由于服务比较特殊,应该会在Windows的事件管理器中留下日志,经查看,日志为

服务启动失败系统事件

可以看到系统日志中并无异常。

问题还不只如此,当Debug版本通过 RegServer 注册后,程序也是启动后立即停止。

既然如此,那就开始使用神器——单步调试。

启动失败原因

Window服务程序启动后,会在WinMain方法中调用一个Run方法

HRESULT Run(_In_ int nShowCmd = SW_HIDE) throw()
{
    HRESULT hr = S_OK;

    T* pT = static_cast<T*>(this);
    hr = pT->PreMessageLoop(nShowCmd);

    // Call RunMessageLoop only if PreMessageLoop returns S_OK.
    if (hr == S_OK)
    {
        pT->RunMessageLoop();
    }

    // Call PostMessageLoop if PreMessageLoop returns success.
    if (SUCCEEDED(hr))
    {
        hr = pT->PostMessageLoop();
    }

    ATLASSERT(SUCCEEDED(hr));
    return 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

或者通过预处理器来定义

无Com接口的服务项目预处理器

系列链接

玩转Windows服务系列——创建Windows服务

玩转Windows服务系列——Debug、Release版本的注册和卸载,及其原理

玩转Windows服务系列——无COM接口Windows服务启动失败原因及解决方案

玩转Windows服务系列——服务运行、停止流程浅析

玩转Windows服务系列——Windows服务小技巧

玩转Windows服务系列——命令行管理Windows服务

 
目录
相关文章
|
3月前
|
SQL Apache Windows
Windows服务器80端口被占用的全面解决方案
在服务管理器中启动apache2服务,即可正常使用80端口。若系统中还安装了其他微软产品如sql等,也可尝试停止其服务进行测试,但请注意,SQL通常不会使用80端口,因此一般不会受到影响。以上就是关于80端口被system占用的详细解决方法,希望对你有所帮助。
|
8天前
|
安全 Linux iOS开发
Tenable Nessus 10.10 (macOS, Linux, Windows) - 漏洞评估解决方案
Tenable Nessus 10.10 (macOS, Linux, Windows) - 漏洞评估解决方案
82 0
Tenable Nessus 10.10 (macOS, Linux, Windows) - 漏洞评估解决方案
|
2月前
|
安全 Linux iOS开发
Tenable Nessus 10.9.3 (macOS, Linux, Windows) - 漏洞评估解决方案
Tenable Nessus 10.9.3 (macOS, Linux, Windows) - 漏洞评估解决方案
239 0
Tenable Nessus 10.9.3 (macOS, Linux, Windows) - 漏洞评估解决方案
|
7月前
|
安全 Unix Linux
Veritas NetBackup 11 for Linux & Windows - 领先的企业备份和恢复解决方案
Veritas NetBackup 11 for Linux & Windows - 领先的企业备份和恢复解决方案
177 0
Veritas NetBackup 11 for Linux & Windows - 领先的企业备份和恢复解决方案
|
3月前
|
监控 数据安全/隐私保护 Windows
Veeam Data Platform 12.3.2 (Windows) - 数据保护和管理解决方案
Veeam Data Platform 12.3.2 (Windows) - 数据保护和管理解决方案
78 1
|
6月前
|
存储 安全 Linux
Nexpose 8.4.1 for Linux & Windows - 领先的漏洞管理解决方案
Nexpose 8.4.1 for Linux & Windows - 领先的漏洞管理解决方案
126 0
Nexpose 8.4.1 for Linux & Windows - 领先的漏洞管理解决方案
|
9月前
|
监控 搜索推荐 开发工具
2025年1月9日更新Windows操作系统个人使用-禁用掉一下一些不必要的服务-关闭占用资源的进程-禁用服务提升系统运行速度-让电脑不再卡顿-优雅草央千澈-长期更新
2025年1月9日更新Windows操作系统个人使用-禁用掉一下一些不必要的服务-关闭占用资源的进程-禁用服务提升系统运行速度-让电脑不再卡顿-优雅草央千澈-长期更新
686 2
2025年1月9日更新Windows操作系统个人使用-禁用掉一下一些不必要的服务-关闭占用资源的进程-禁用服务提升系统运行速度-让电脑不再卡顿-优雅草央千澈-长期更新
|
11月前
|
网络安全 Windows
Windows server 2012R2系统安装远程桌面服务后无法多用户同时登录是什么原因?
【11月更文挑战第15天】本文介绍了在Windows Server 2012 R2中遇到的多用户无法同时登录远程桌面的问题及其解决方法,包括许可模式限制、组策略配置问题、远程桌面服务配置错误以及网络和防火墙问题四个方面的原因分析及对应的解决方案。
849 4
|
12月前
|
边缘计算 安全 网络安全
|
11月前
|
数据库 数据安全/隐私保护 Windows
Windows远程桌面出现CredSSP加密数据修正问题解决方案
【10月更文挑战第30天】本文介绍了两种解决Windows系统凭据分配问题的方法。方案一是通过组策略编辑器(gpedit.msc)启用“加密数据库修正”并将其保护级别设为“易受攻击”。方案二是通过注册表编辑器(regedit)在指定路径下创建或修改名为“AllowEncryptionOracle”的DWORD值,并将其数值设为2。
9063 3