在WiX安装程序中安装和启动Windows服务失败。

15

我正在使用WiX v3.8创建一个MSI包,用于安装和启动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.

我如何修复这些错误?


你找到解决方案了吗? - kudlatiger
7个回答

13
您收到的错误消息是Windows Installer在安装过程中启动服务失败时发送的通用消息。几乎总是由于服务缺少依赖项或在启动时未完全配置引起的问题。要调试根本问题,请尝试以下操作:
  1. 安装MSI包。
  2. 当出现指示服务启动失败的错误对话框时,*请勿关闭对话框。
  3. 启动services.msc或使用命令行中的sc.exe尝试启动服务。Windows Installer应该已经配置了足够的服务以深入调试其失败原因。
  4. 如有必要,请直接调试到您的服务可执行文件,以查看它无法启动的原因。

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

祝您调试服务好运!


1
嗨罗布,虽然这个问题听起来很蠢,但我如何知道我的可执行文件是否依赖于GAC中的某个文件? - Mahadeva

6
在 OP 的示例中,ServiceInstall 帐户是被混淆的,但是如果忘记完全限定帐户,就会发生此错误,例如:

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

如果只指定用户名而没有 NT Authority,如下所示,则安装程序将失败:

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


与此答案相关:如果您为[SERVICEACCOUNT]使用本地帐户,请确保包括计算机名称,而不仅仅是帐户名称。例如,MYSERVER\UserX将起作用,而仅使用UserX将无法工作。当然,如果这是域帐户,则需要指定域名。 - Alek Davis

4

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

要在本地计算机上为一个帐户添加“作为服务登录”权限,请执行以下操作:

1)打开本地安全策略。

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

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

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

来源:http://technet.microsoft.com/zh-cn/library/cc739424%28v=ws.10%29.aspx


0

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

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


0

我也遇到了这个问题,在安装过程中出现了错误,尽管服务注册表键已经创建并且我能够手动启动服务。

所以我是这样解决的:

不要使用服务控制在安装时立即启动服务:

  <ServiceControl Id="StartService"
                  Start="install" 
                  .. />

我刚刚从ServiceControl中删除了Start,这样安装程序的成功就不再依赖于服务的启动。在成功安装后,您只需要手动启动服务即可,这可以通过脚本轻松完成。


0
今天我遇到了这个错误,因为我的服务有依赖项,在启动服务之前必须将它们GACed。结果证明,安装程序最后才会将依赖项GACed,没有什么好的方法可以解决这个问题,除非构建某种引导程序/多部分安装程序。
然而,我找到了以下解决方案:将程序集部署到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>

现在它可以工作了!


0
只是想在这里补充我的解决方案,以防有人像我一样遇到这个问题...
我有一个 .msi 文件,正在安装服务,在某个特定的时刻,会弹出一个对话框,上面写着:“服务...无法启动。请验证您是否具有足够的权限来启动系统服务。”当然,我拥有所有的权限...一旦我为它生成了一个日志文件
msiexec -i package.msi /L*V package.log
在日志文件中找到了以下内容:
Error 1920. Service 'Controller 01' (Controller01) failed to start. Verify that you have sufficient privileges to start system services.
MSI (s) (04:5C) [12:23:11:831]: I/O on thread 2052 could not be cancelled. Error: 1168
MSI (s) (04:5C) [12:23:11:831]: I/O on thread 5396 could not be cancelled. Error: 1168
MSI (s) (04:5C) [12:23:11:831]: I/O on thread 5404 could not be cancelled. Error: 1168
MSI (s) (04:5C) [12:23:11:831]: I/O on thread 1448 could not be cancelled. Error: 1168
MSI (s) (04:5C) [12:23:11:831]: I/O on thread 1904 could not be cancelled. Error: 1168
MSI (s) (04:5C) [12:23:11:831]: I/O on thread 1088 could not be cancelled. Error: 1168
MSI (s) (04:5C) [12:23:11:831]: I/O on thread 6952 could not be cancelled. Error: 1168
MSI (s) (04:5C) [12:23:11:831]: I/O on thread 6956 could not be cancelled. Error: 1168

在事件查看器中没有找到帮助,所以在我点击安装程序的取消按钮之前,我去了硬盘上服务的位置,并尝试以管理员身份运行它。在这一点上,我得到了一个线索,最终帮助我修复了这个问题:

找不到MSVCR120.dll

在这一点上,我去了c:\windows\system32并查找了这个DLL文件...它在那里。所以,我直接将它复制到带有.exe文件的目录中,并再次尝试运行它。这次我得到了一个不同的错误信息:

应用程序无法正确启动(0xc000007b)

搜索“0xc000007b”的含义时,我发现这里解释了它的意思:“错误代码0xc000007b代表STATUS_INVALID_IMAGE_FORMAT。这意味着一个应用程序试图加载错误的CPU架构的DLL文件。因此,32位应用程序试图加载64位的DLL文件,或者64位应用程序试图加载32位的DLL文件。”
所以在我的情况下,安装程序的发布者没有包含x86 Visual C++ Redistributable Package for Visual Studio 2013。安装了该程序并重新启动后,我再次运行了安装程序,结果成功了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接