【问题标题】:Failed to install and start Windows services in WiX installer在 WiX 安装程序中安装和启动 Windows 服务失败
【发布时间】:2013-04-24 09:34:33
【问题描述】:

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

如何修复错误?

【问题讨论】:

  • 你找到解决办法了吗?

标签: windows-services wix wix3.8


【解决方案1】:

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

  1. 安装 MSI 包。
  2. 出现错误对话框时,指示服务启动失败 *不要关闭对话框。
  3. 启动 services.msc 或使用命令行中的 sc.exe 来尝试启动您的服务。 Windows 安装程序应该已经配置了足够多的服务,以便能够更深入地调试失败的原因。
  4. 如有必要,直接调试到您的服务可执行文件以查看它无法启动的原因。

如果这是用托管代码编写的服务,请确保它依赖于放置在 GAC 中的文件。直到安装过程中的非常非常晚的时候,文件才会出现在 GAC 中。如果您必须在 GAC 中使用文件,您将无法使用内置的 ServiceControl 元素,并且必须编写自定义操作以在 InstallFinalize 之后运行。请注意,在InstallFinalize 之后,将不会提升自定义操作,因此您的服务必须支持由非提升用户启动。同样,我建议不要依赖 GAC。

祝你调试服务好运!

【讨论】:

  • 嗨 Rob,虽然这个问题听起来很愚蠢,但是我如何知道我的可执行文件是否依赖于 GAC 中的某个文件?
【解决方案2】:

在 OP 的示例中,ServiceInstall 帐户被混淆了,但如果忘记完全限定帐户,则可能会发生此错误,如下所示:

&lt;ServiceInstall ... Account="NT AUTHORITY\LocalService" /&gt;

如果您只指定用户名(没有 NT 授权),您的安装程序将失败:

&lt;ServiceInstall ... Account="LocalService" /&gt;

【讨论】:

  • 与此答案相关:如果您为 [SERVICEACCOUNT] 使用本地帐户,请确保包含计算机名称,而不仅仅是帐户名称。例如。 MYSERVER\UserX 将起作用,而只是 UserX 将不起作用。而且,当然,你需要指定域名这是一个域帐户。
【解决方案3】:

记得将“作为服务登录”权限添加到 [SERVICEACCOUNT],

将“作为服务登录”权限添加到本地计算机上的帐户

1) 打开本地安全策略。

2) 在控制台树中,双击Local Policies,然后单击User Rights Assignments

3) 在详细信息窗格中,双击作为服务登录

4) 点击添加用户或组,然后将相应的帐户添加到拥有作为服务登录权限的帐户列表中。

发件人:http://technet.microsoft.com/en-us/library/cc739424%28v=ws.10%29.aspx

【讨论】:

    【解决方案4】:

    在调试服务启动问题时,我总是只使用一个简单的 if() 语句来检查安装目录中是否存在特定文件。当服务失败时,我打开一个命令提示符(在关闭指示失败的对话框之前)并使用“echo >thatfile”来创建我在 if() 中寻找的文件。 if() 的对象是 Debugger.Launch() 调用。

    现在,我可以关闭对话框并重新运行安装程序,这一次它将启动调试器,我可以看到会发生什么。我倾向于使用静态类初始化作为启动调试器的时刻,但是您可以尝试在“OnStart()”中执行此操作,但如果存在加载/绑定问题,您可能无法在它死掉之前到达那一点.而在静态类初始化期间执行此操作几乎总是会告诉您需要作为依赖项解决的事情。

    【讨论】:

      【解决方案5】:

      所以我今天收到了这个错误,因为我的服务具有必须在启动服务之前进行 GAC 的依赖项。事实证明,安装程序最后对依赖项进行 GAC,如果不构建某种引导程序/多部分安装程序,真的没有好办法解决这个问题。

      但是,我找到了以下解决方案:将程序集都部署到 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>
      

      现在它可以工作了!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-15
        相关资源
        最近更新 更多