我正在创建一个MSI软件包,用于使用WiX v3.8安装和启动Windows服务。代码如下:
<Component Id="INSTALLAPSSERVICE" Guid="991D5F82-0E77-4FE3-B1D8-4C941B84C7CD" Win64="yes">
<File Id="ApsService.exe"
Name="ApsService.exe"
Source="Resource\ApsService.exe"
KeyPath="yes"
Vital="yes"
DiskId="1"></File>
<ServiceInstall Id="ApsServiceInstaller"
Name="ApsService"
DisplayName="ApsService"
Type="ownProcess"
Start="auto"
ErrorControl="normal"
Description="A monitor service for windows application."
Account="[SERVICEACCOUNT]"
Password="[SERVICEPASSWORD]"
Vital="yes"
Interactive="no"></ServiceInstall>
<ServiceControl Id="StartService"
Start="install"
Stop="both"
Remove="uninstall"
Name="ApsService"
Wait="yes"/>
</Component>
但安装失败,并在日志中出现以下错误:
Executing op: ServiceControl(,Name=ApsService,Action=1,Wait=1,)
StartServices: Service: ApsService
Error 1920. Service 'ApsService' (ApsService) failed to start. Verify that you have sufficient privileges to start system services.
MSI (s) (F0:D0) [15:57:28:630]: I/O on thread 3676 could not be cancelled. Error: 1168
MSI (s) (F0:D0) [15:57:28:630]: I/O on thread 1888 could not be cancelled. Error: 1168
MSI (s) (F0:D0) [15:57:28:630]: I/O on thread 1764 could not be cancelled. Error: 1168
MSI (s) (F0:D0) [15:57:28:630]: I/O on thread 3504 could not be cancelled. Error: 1168
MSI (s) (F0:D0) [15:57:28:630]: I/O on thread 2100 could not be cancelled. Error: 1168
MSI (s) (F0:D0) [15:57:28:630]: I/O on thread 2752 could not be cancelled. Error: 1168
MSI (s) (F0:D0) [15:57:28:630]: I/O on thread 3672 could not be cancelled. Error: 1168
MSI (s) (F0:D0) [15:57:28:630]: I/O on thread 3876 could not be cancelled. Error: 1168
MSI (s) (F0:D0) [15:57:28:630]: I/O on thread 1400 could not be cancelled. Error: 1168
MSI (s) (F0:C0) [15:57:28:630]: Product: WinApsSetup64 -- Error 1920. Service 'ApsService' (ApsService) failed to start. Verify that you have sufficient privileges to start system services.
如何修复错误?
答案 0 :(得分:13)
您收到的错误消息是Windows Installer在安装期间无法启动服务时发送的通用消息。问题几乎总是服务缺少依赖关系,或者在启动时没有完全配置。要调试根问题,请尝试:
如果这是使用托管代码编写的服务,请确保不依赖于放置在GAC中的文件。在安装过程中非常非常晚,文件不在GAC中。如果您必须使用GAC中的文件,则无法使用内置的ServiceControl
元素,并且必须编写自定义操作以在InstallFinalize
之后运行。请注意,在InstallFinalize
之后,自定义操作不会被提升,因此您的服务必须支持由非提升用户启动。同样,我建议不要依赖GAC。
祝你好运调试服务!
答案 1 :(得分:6)
在OP的示例中对ServiceInstall帐户进行了模糊处理,但如果忘记完全限定帐户,则会发生此错误:
<ServiceInstall ... Account="NT AUTHORITY\LocalService" />
如果您只指定用户名(没有NT权限),您的安装程序将失败:
<ServiceInstall ... Account="LocalService" />
答案 2 :(得分:4)
请务必在[SERVICEACCOUNT]
中添加“作为服务登录”权限将“作为服务登录”权限添加到本地计算机上的帐户
1)打开本地安全策略。
2)在控制台树中,双击本地政策,然后点击用户权限分配。
3)在详细信息窗格中,双击作为服务登录。
4)点击添加用户或群组,然后将相应的帐户添加到拥有作为服务登录权限的帐户列表中。
来自:http://technet.microsoft.com/en-us/library/cc739424%28v=ws.10%29.aspx。
答案 3 :(得分:0)
调试服务启动问题时,我总是只使用一个简单的if()语句来检查安装目录中是否存在特定文件。当服务失败时,我打开一个命令提示符(在解除指示失败的对话框之前)并使用“echo&gt; thatfile”来创建我在if()中寻找的文件。 if()的对象是Debugger.Launch()调用。
现在,我可以关闭对话框并重新运行安装程序,这次它将启动调试器,我可以看到会发生什么。我倾向于使用静态类init作为启动调试器的时刻,但您可以尝试在“OnStart()”中执行此操作,但如果存在加载/绑定问题,您可能无法在它死之前达到这一点。而在静态类init期间执行此操作几乎总是会告诉您需要作为依赖项解决的问题。
答案 4 :(得分:0)
所以今天我收到了这个错误,因为我的服务有依赖关系,必须在启动服务之前进行GAC。事实证明,安装程序最后会依赖GACed,并且在没有构建某种bootstraper / multipart安装程序的情况下,实际上没有好办法解决这个问题。
但是,我发现了以下解决方案:将程序集部署到GAC并将它们安装在与服务相同的目录中。这样,服务将能够在程序文件目录中找到启动时的DLL,并且它们将被GACed(这是其他原因的要求)。
为此,我必须创建两个单独的组件组和一个“虚拟”目录:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="NameOfProgram" />
<Directory Id="GacDlls" Name="libs" />
</Directory>
</Directory>
然后我创建了两个组件组:一个具有exe和所有库,另一个具有相同的库,其Assembly属性设置为“.net”:
<ComponentGroup Id="ServiceLibs" Directory="GACDlls">
<Component Id="log4netGAC"
Guid="a23099ac-5880-4b6e-af3f-fa7cef113226">
<File Id="log4net.dllGAC"
Name="log4net.dll"
Source="..\ProjectDir\bin\$(var.Configuration)\log4net.dll"
KeyPath="yes"
Vital="yes"
DiskId="1"
Assembly=".net"
/>
</Component>
</ComponentGroup>
<ComponentGroup Id="ProductComponents" Directory="INSTALLDIR">
<Component Id="log4net"
Guid="463e05db-e248-44d7-bbde-467358b7310f">
<!-- normally we'd want to GAC this (Assembly=".net"), but that would prevent us from starting the service up during install so we'll just drop it in the program folder -->
<File Id="log4net.dll"
Name="log4net.dll"
Source="..\ProjectName\bin\$(var.Configuration)\log4net.dll"
KeyPath="yes"
Vital="yes"
DiskId="1"
/>
</Component>
... other components ...
</ComponentGroup>
现在它有效!