15

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

如何修复错误?

4

5 回答 5

13

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

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

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

祝您调试服务好运!

于 2013-04-24T12:20:02.607 回答
6

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

<ServiceInstall ... Account="NT AUTHORITY\LocalService" />

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

<ServiceInstall ... Account="LocalService" />

于 2013-08-19T21:13:05.597 回答
4

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

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

1) 打开本地安全策略。

2) 在控制台树中,双击本地策略,然后单击用户权限分配

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

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

来自:http ://technet.microsoft.com/en-us/library/cc739424%28v=ws.10%29.aspx 。

于 2013-10-04T16:59:30.513 回答
0

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

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

于 2014-03-01T19:53:12.663 回答
0

所以我今天收到了这个错误,因为我的服务有依赖项,必须在启动服务之前进行 GACed。事实证明,安装程序最后对依赖项进行 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>

现在它起作用了!

于 2015-02-19T20:40:53.220 回答