2011-03-24 137 views
4

我需要安裝和運行一個服務安裝應用程序時(使用Inno Setup的創建Installer.exe的)在Windows上安裝服務(VISTA/XP/7)使用Inno Setup的

我用下面

[Run] 
Filename:"{sys}\myservice.exe "; Parameters: "-install" 

我不知道這是否是正確的

(我添加代碼,以提示重新啓動,但我不知道是否有可能無需重新啓動電腦在安裝後立即運行服務。)

[Setup] 
AlwaysRestart=yes 

歡迎發表評論。

+1

服務可以在安裝後立即運行,我一直這樣做。儘管如果安裝程序必須替換正在使用的文件,可能需要重新引導。 – 2011-03-24 07:46:22

+0

如果我記得,安裝服務的建議不是使用服務的自行安裝,而是直接從安裝程序寫入所有註冊表項。 – 2011-03-24 07:55:22

+0

AFAIK您應該使用SCM(服務控制管理器)API來安裝服務,而不是訪問註冊表。 – 2011-03-24 08:48:07

回答

11
  1. 使用SC.exe,這很簡單,唯一的缺點是,你可能要攔截並解析輸出到知道自己錯在哪裏,如果它沒有。
  2. 使用我的Inno Setup service library。它是SCM API的Pascal腳本封裝器,可讓您完全控制服務。使用起來稍微複雜一點,但它允許進行全面的錯誤檢查和處理。有一些更高級別的功能可以在標準的可壓縮Inno Setup對話框中顯示錯誤。

PS:不要將您的服務安裝在任何Windows系統文件夾中。他們應該被視爲Windows私人文件夾。除非你有非常充分的理由(例如驅動程序),否則你不應該在那裏安裝軟件。將它安裝在應用程序文件夾中。

+0

+1不錯的圖書館,我會用這:)取代我的本土功能服務:) – jachguate 2011-03-24 15:03:31

+0

+1真棒圖書館(不只是很好)。到目前爲止,在Unicode版本中沒有發現任何問題。 – 2014-01-27 22:54:14

1

使用Service Functions的Inno Setup的從西爾維奧Iaccarino

+1

但是,如果您使用的是Unicode版本的Inno Setup,請小心,否則這些腳本將無法使用。查看@ldsandon的答案 - 並記下他的「服務庫」頁面底部的鏈接。 – shunty 2011-03-24 09:02:11

1

除了接受的答案,我只想讓人們更容易使用Luigi Sandon的服務庫(非常感謝!)。下載腳本後,您就需要添加一個[代碼]類似於以下到你的安裝腳本部分:

[Code] 
// source: https://stackoverflow.com/a/5416744 
#include "services_unicode.iss" 

const 
    SERVICE_NAME = 'MyService'; 
    SERVICE_DISPLAY_NAME = 'MyService'; 
    SERVICE_EXE = 'MyService.exe'; 

procedure CurStepChanged(CurStep: TSetupStep); 
begin 
    Log('CurStepChanged(' + IntToStr(Ord(CurStep)) + ') called'); 

    if CurStep = ssInstall then begin 
    if ServiceExists(SERVICE_NAME) then begin 
     if SimpleQueryService(SERVICE_NAME) = SERVICE_RUNNING then begin 
     SimpleStopService(SERVICE_NAME, True, False); 
     end; 
     SimpleDeleteService(SERVICE_NAME); 
    end; 
    end 
    else if CurStep = ssPostInstall then begin 
    SimpleCreateService(SERVICE_NAME, SERVICE_DISPLAY_NAME, ExpandConstant('{app}\' + SERVICE_EXE), SERVICE_AUTO_START, '', '', False, False); 
    SimpleStartService(SERVICE_NAME, True, False); 
    end; 
end; 

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); 
begin 
    Log('CurUninstallStepChanged(' + IntToStr(Ord(CurUninstallStep)) + ') called'); 

    if CurUninstallStep = usUninstall then begin 
    if ServiceExists(SERVICE_NAME) then begin 
     if SimpleQueryService(SERVICE_NAME) = SERVICE_RUNNING then begin 
     SimpleStopService(SERVICE_NAME, True, False); 
     end; 
     SimpleDeleteService(SERVICE_NAME); 
    end; 
    end; 
end; 

這不是防彈的,但應該處理絕大多數情況下就好了。

不幸的是我無法弄清楚是否有使用{# VarName}發出的[代碼]部分的語法,這就是爲什麼我宣佈服務名稱等作爲常量有以及#define的一種方式在文件的頂部。答案here很有用如果你想要的常數是[Setup]部分的設置之一,但是因爲你不能隨意添加東西到這個部分,所以你不想爲所有的東西定義常量。

如果您想爲您服務的描述,則服務庫不支持,但是這是很容易使用[註冊]部分做的,例如:

[Registry] 
; set the service description 
Root: HKLM; Subkey: "System\CurrentControlSet\Services\{#ServiceName}"; ValueType: string; ValueName: "Description"; ValueData: "{#ServiceDescription}"; Flags: deletevalue uninsdeletekey 

最後,我可以確認這也適用於Windows 10。