2013-04-24 166 views
13

我正在创建一个MSI程序包,用于使用WiX v3.8安装和启动Windows服务。代码如下:无法在WiX安装程序中安装并启动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. 

我如何解决这个错误?

回答

12

您收到的错误消息是Windows安装程序在安装期间无法启动服务时发送的通用消息。几乎总是存在这样的问题,即服务缺少依赖性,或者在启动时没有完全配置。要调试其根源问题的尝试:

  1. 安装MSI软件包。
  2. 当错误对话框出现时,表明服务启动失败* 不要关闭对话框。
  3. 启动services.msc或从命令行使用sc.exe来尝试启动服务。 Windows安装程序应该配置足够的服务,以便能够更深入地调试它失败的原因。
  4. 如果需要,直接调试到您的服务可执行文件,看看它为什么不能启动。

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

祝你好运调试你的服务!

+1

Hi Rob,虽然问题听起来可能是假的,但我怎么知道我的可执行文件是否依赖于GAC中的某个文件? – Pant 2015-03-11 15:48:16

+0

这与我合作,谢谢 – jovenb 2015-11-12 10:48:02

6

则ServiceInstall帐户混淆在OP的例子,但如果忘记完全限定帐户可能发生这种错误,因为这样的:

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

你的安装程序会如果只指定用户名失败(W/O的NT AUTHORITY)是这样的:

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

+0

与此答案相关:如果您使用[SERVICEACCOUNT]的本地帐户,请确保您包含计算机的名称,而不仅仅是帐户名称。例如。 MYSERVER \ UserX将工作,而只有UserX将无法工作。而且,当然,您需要指定域名是这是一个域帐户。 – 2013-10-05 05:48:22

4

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

要添加“日志上作为服务”的权利,你的本地计算机

1)打开本地安全策略的帐户。

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

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

4)点击添加用户或组,然后添加适当的帐户到拥有登录作为服务正确的帐户列表。

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

0

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

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

0

因此,我今天得到了这个错误,因为我的服务在启动服务之前必须要有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> 

现在它的工作原理!