2013-04-24 162 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> 

現在它的工作原理!