我正在处理循环依赖w.r.t. Windows服务及其对驱动程序的依赖。情况如下:
我用C ++编写了一个Windows服务。此服务依赖于DLL,它在第一次加载/使用时安装驱动程序; DLL在此期间的操作中使用驱动程序。
在早期测试中,我会通过对带有/INSTALL
标志的服务可执行文件的命令行调用来安装服务 - 这将在内部调用InstallService
。
然后我遇到了一个问题:当我手动启动它时服务会运行,但是当它被设置为在启动后自动运行时它会在驱动程序加载之前启动,因此会出错。
要解决此问题,我在HKLM\System\CurrentControlSet\Services\<SERVICE>
的服务的注册表项DependOnService
中为驱动程序设置了服务依赖项 - Windows将驱动程序视为类似于服务的驱动程序值。这解决了这个问题。
快进部署:我正在使用WiX来安装和启动服务。在安装过程中,我想将驱动程序设置为我的服务的依赖项。但是,如果我将驱动程序定义为ServiceInstall
元素中的依赖项,那么WiX会在启动服务之前尝试启动它,因此我的问题是:WiX无法在不启动依赖项的情况下启动服务,并且依赖关系不在那里,因为服务还没有运行。
如果我没有在安装程序配置文件中指定依赖项,那么该服务将安装并运行正常。
我想我可以像以前一样在注册表中安装服务后定义依赖项,但那里没有服务条目!
另一件事:服务现在在启动后运行!没有定义依赖!我还没有做太多测试,看看这是否一致。
那么,WiX如何告诉Windows有一项服务,即为什么没有注册表项呢?如何指定依赖项?我甚至需要再指定一个吗?我是否应该放弃使用与WiX服务相关的元素并运行我在安装程序中手动测试期间执行的命令?
我一直在努力研究并研究至少一周;我们将不胜感激。
环境信息:
答案 0 :(得分:1)
我找到了解决方案。
很多问题都是RTFM问题(虽然我的辩护是文件不是很清楚):
我一直在使用通用名称来表示ServiceInstall
元素Name
属性的值 - 我认为这用于链接ServiceInstall
元素到ServiceControl
元素。
ServiceInstall
元素的文档说明了Name
属性的以下内容:
此列是提供要安装的服务名称的字符串。
ServiceControl
元素的文档说:
服务名称。
Name
属性值的实际用途是服务的隐藏系统名称;这是HKLM\System\CurrentControlSet\Services
下注册表中使用的名称。因此,我的服务是在ServiceManagement
密钥下安装的,因为这是我在Name
属性中所拥有的。
不同的名称是导致依赖性工作的原因。显然,除非依赖性,Windows按字母顺序加载服务(请参阅this answer上的注释)。当我手动安装时,我的服务的名称在驱动程序之前,因此在未指定依赖项时出错。我在WiX项目的Name
属性中指定的通用名称是在驱动程序的服务名称之后,因此驱动程序在我的服务之前就已加载了。
我最终做的是将Name
切换回服务的正确名称,然后向WiX项目添加RegistryValue
以指定我的服务对驱动程序的依赖(服务) )。