无法在WiX安装程序中安装和启动Windows服务

时间:2013-04-24 09:34:33

标签: windows-services wix wix3.8

我正在创建一个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.

如何修复错误?

5 个答案:

答案 0 :(得分:13)

您收到的错误消息是Windows Installer在安装期间无法启动服务时发送的通用消息。问题几乎总是服务缺少依赖关系,或者在启动时没有完全配置。要调试根问题,请尝试:

  1. 安装MSI包。
  2. 当出现错误对话框时指示无法启动服务* 关闭对话框。
  3. 启动services.msc或使用命令行中的sc.exe尝试启动服务。 Windows Installer应该已经配置了足够的服务,以便能够更深入地调试它失败的原因。
  4. 如有必要,请直接调试服务可执行文件以查看无法启动的原因。
  5. 如果这是使用托管代码编写的服务,请确保依赖于放置在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>

现在它有效!