Inno Setup for Windows service


I have a .Net Windows service. I want to create an installer to install that windows service.

Basically, it has to do the following:

  1. Pack installutil.exe (Is it required?)
  2. Run installutil.exe MyService.exe
  3. Start MyService

Also, I want to provide an uninstaller which runs the following command:

installutil.exe /u MyService.exe

How to do these using Inno Setup?

share improve this question
 
    
I think you need to use the [Run] section. See here – Preet Sangha Sep 20 '09 at 1:16

4 Answers

up vote 185down voteaccepted

You don't need installutil.exe and probably you don't even have rights to redistribute it.

Here is the way I'm doing it in my application:

using System; using System.Collections.Generic; using System.Configuration.Install; using System.IO; using System.Linq; using System.Reflection; using System.ServiceProcess; using System.Text; static void Main(string[] args) { if (System.Environment.UserInteractive) { string parameter = string.Concat(args); switch (parameter) { case "--install": ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location }); break; case "--uninstall": ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location }); break; } } else { ServiceBase.Run(new WindowsService()); } }

Basically you can have your service to install/uninstall on its own by using ManagedInstallerClassas shown in my example.

Then it's just matter of adding into your InnoSetup script something like this:

[Run] Filename: "{app}\MYSERVICE.EXE"; Parameters: "--install" [UninstallRun] Filename: "{app}\MYSERVICE.EXE"; Parameters: "--uninstall"
share improve this answer

 

 

 

 

 

 

 

 

 

 

 

Inno Setup的常用腳本

 分類:
安裝不同的目錄:
[Files]
Source: "我的程序\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "我的程序\*"; DestDir: {cf}\我的程序; Flags: ignoreversion recursesubdirs createallsubdirs
 
開始菜單快捷方式: 
[Icons]
Name: "{group}\我的程序名稱"; Filename: "{app}\我的程序.exe" ;WorkingDir: "{app}" 

桌面快捷方式: 
[Icons]
Name: "{userdesktop}\我的程序名稱"; Filename: "{app}\我的程序.exe"; WorkingDir: "{app}" 

開始菜單卸載快捷方式: 
[Icons]
Name: "{group}\{cm:UninstallProgram,我的程序}"; Filename: "{uninstallexe}" 

安裝完后選擇運行: 
[Run]
Filename: "{app}\我的程序.exe"; Description: "{cm:LaunchProgram,我的程序名稱}"; Flags: nowait postinstall skipifsilent 

安裝完后自動運行: 
[Run]
Filename: "{app}\我的程序.exe"; 

在界面左下角加文字: 
[Messages]
BeveledLabel=你的網站名稱 

選擇組件安裝:(組件1的Flags: fixed為必須安裝) 
[Types] 
Name: "full"; Description: "選擇安裝"; Flags: iscustom 
[Components] 
Name: 組件1文件夾; Description: 組件1名稱; Types: full; Flags: fixed 
Name: 組件2文件夾; Description: 組件2名稱; Types: full 
Name: 組件3文件夾; Description: 組件3名稱; Types: full 
[Files] 
Source: "E:\組件1文件夾\我的程序.exe"; DestDir: "{app}"; Flags: ignoreversion 
Source: "E:\組件1文件夾\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Components: 組件1文件夾 
Source: "E:\組件2文件夾\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Components: 組件2文件夾 
Source: "E:\組件3文件夾\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Components: 組件3文件夾 

添加關於按鈕: 
[Code] 
{注意:關於按鈕單擊后執行的過程,一定要寫在InitializeWizard()過程之前} 
procedure ButtonAboutOnClick(Sender: TObject); 
begin 
MsgBox('關於對話框。'+#13#10+'另起一行', mbInformation, MB_OK);//顯示對話框 
end; 
{初始化安裝向導時會觸發的過程,這個過程的名字是INNO內部定義的,不能修改} 
procedure InitializeWizard(); 
begin 
with TButton.Create(WizardForm) do//在WizardForm上面創建一個按鈕 
begin 
Left := 32;//按鈕距WizardForm左邊的距離 
Top := 302;//按鈕距WizardForm上邊的距離 
Width := WizardForm.CancelButton.Width;//按鈕的寬度,這里定義跟'取消'按鈕等寬 
Height := WizardForm.CancelButton.Height;//按鈕的高度 
Caption := '關於(&A)...';//按鈕上的文字 
Font.Name:='宋體';//按鈕文字的字體 
Font.Size:=9;//9號字體 
OnClick := @ButtonAboutOnClick;//單擊按鈕觸發的過程,就是前面的'ButtonAboutOnClick'過程,注意前面不要漏掉 
Parent := WizardForm;//按鈕的父組件,也就是按鈕'載體',這里是WizardForm(安裝向導窗體) 
end; 
end; 

設置界面文字顏色: 
[Code] 
procedure InitializeWizard(); 
begin 
WizardForm.WELCOMELABEL1.Font.Color:= clGreen;//設置開始安裝頁面第一段文字的顏色為綠色 
WizardForm.WELCOMELABEL2.Font.Color:= clOlive;//設置開始安裝頁面第二段文字的顏色為橄欖綠 
WizardForm.PAGENAMELABEL.Font.Color:= clred;//設置許可協議頁面第一段文字的顏色為紅色 
WizardForm.PAGEDESCRIPTIONLABEL.Font.Color:= clBlue; //設置許可協議頁面第二段文字的顏色為藍色 
WizardForm.MainPanel.Color:= clWhite;//設置窗格的顏色為白色 
end; 

判斷所選安裝目錄中原版主程序是否存在:
[Code] 
function NextButtonClick(CurPage: Integer): Boolean; 
begin 
Result:= true; 
if CurPage=wpSelectDir then 
if not FileExists(ExpandConstant('{app}\主程序.exe')) then 
begin 
MsgBox('安裝目錄不正確!', mbInformation, MB_OK ); 
Result := false; 
end; 
end;
 
 
注:
{app}表示默認安裝路徑為C:\Program Files\我的程序\
{cf}表示默認安裝路徑為C:\Program Files\Common Files\我的程序\

顏色:
clBlack(黑色),clMaroon(暗紅),clGreen(綠色),clOlive(橄欖綠),clNavy(深藍),clPurple(紫色),clTeal(深青),clGray(灰色),clSilver(淺灰),clRed(紅色),clLime(淺綠),clYellow(黃色),clBlue(藍色),clFuchsia(紫紅),clAqua(青綠),clWhite(白色)。te(白色)。
增加path路徑:
[Register]
Root: HKLM; Subkey: "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; ValueName: "Path"; ValueData: "{olddata};{app}";Flags:uninsdeletekey
 

0、調用DOS命令或批處理等其它命令行工具等

Exec(ExpandConstant('{cmd}'), '/c dir c:\ >a.txt',ExpandConstant('{app}'), SW_SHOWNORMAL, ewNoWait, ResultCode);

1、不顯示一些特定的安裝界面 
[code]
function ShouldSkipPage(PageID: Integer): Boolean; 
begin 
if PageID=wpReady then 
result := true; 
end;
wpReady 是准備安裝界面
PageID查詢 INNO幫助中的 Pascal 腳本: 事件函數常量
預定義向導頁 CurPageID 值
wpWelcome, wpLicense, wpPassword, wpInfoBefore, wpUserInfo, wpSelectDir, wpSelectComponents, wpSelectProgramGroup, wpSelectTasks, wpReady, wpPreparing, wpInstalling, wpInfoAfter, wpFinished

如果是自定義的窗體,則PageID可能是100,你可以在curPageChanged(CurPageID: Integer)方法中打印出到curpageid到底是多少。

2、獲取SQLserver安裝路徑
var 
dbpath:string;
rtn:boolean;
rtn := RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\MSSQLServer\Setup','SQLPath', dbpath);
if (!rtn) then dbpath := ExpandConstant('{app}');

3、獲取本機的IP地址
ip:string;
rtn:boolean;

//{083565F8-18F0-4F92-8797-9AD701FCF1BF}視網卡而定見LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards處
rtn :=RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Services\{083565F8-18F0-4F92-8797-9AD701FCF1BF}\Parameters\TcpIp','IpAddress', ip);
if (not rtn) or (ip='0.0.0.0') or (ip='') then ip := '127.0.0.1';

4、檢查數據庫是否安裝
//檢查是否已安裝SQL
try
    CreateOleObject('SQLDMO.SQLServer');
except
    RaiseException('您還沒有安裝SQL數據庫.'#13#13'(Error ''' + GetExceptionMessage + ''' occurred)');
end;

5、根據環境變量選擇組件,獲取系統環境變量值見方法6
procedure CurPageChanged(CurPageID: Integer);
var
path:string;
rtn:boolean;
begin
//MsgBox(inttostr(curpageid),mbInformation,mb_ok);
if (curpageId =7) then
begin
    rtn := checkTomcat6(path);
    if rtn then//如果系統以前沒安裝tomcat則選中組件,否則不選中
    begin
       WizardForm.ComponentsList.CheckItem(2,coUnCheck);
       WizardForm.ComponentsList.ItemEnabled[2] := false;
    end;
end;
end;

6、系統環境變量操作
讀取:
function GetEnv(const EnvVar: String): String;
舉例:GetEnv('java_home')
設置:
[Setup]
ChangesEnvironment=true

[code]
//環境變量名、值、是否安裝(刪除)、是否所有用戶有效
procedure SetEnv(aEnvName, aEnvValue: string; aIsInstall: Boolean);//設置環境變量函數
var
sOrgValue: string;
x,len: integer;
begin
    //得到以前的值
    RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', aEnvName, sOrgValue)
    sOrgValue := Trim(sOrgValue);
    begin
      x := pos( Uppercase(aEnvValue),Uppercase(sOrgValue));
      len := length(aEnvValue);
      if aIsInstall then//是安裝還是反安裝
      begin
          if length(sOrgValue)>0 then aEnvValue := ';'+ aEnvValue;
          if x = 0 then Insert(aEnvValue,sOrgValue,length(sOrgValue) +1);
      end
      else
      begin
         if x>0 then Delete(sOrgValue,x,len);
         if length(sOrgValue)=0 then 
         begin
           RegDeleteValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',aEnvName);
           exit;
         end;
      end;
      StringChange(sOrgValue,';;',';');
      RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', aEnvName, sOrgValue)
    end;
end;

7、獲取NT服務安裝路徑

Windows服務在系統安裝后會在注冊表的 "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\"下
以服務的ServiceName建1個目錄,
目錄中會有"ImagePath"

舉例獲取tomcat6服務安裝路徑:
RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Services\tomcat6','ImagePath', sPath);

------------------------------------------------------------------------
算不上原創,可也花費了很多時間心血查資料、整理、調試

Inno Setup 安裝、卸載前檢測進程或服務

  (2015-04-22 11:15:00)
標簽: 

inno

 

inno打包

 

iss

 

isapprunning

 

psvince.dll

分類: 編程
    在用Inno打包期間遇到了一些小問題,在這里總結一下:
 
Inno.iss部分內容如下:

1、32位程序的PSVince.dll插件方法。
[Files]
Source: psvince.dll; Flags: dontcopy

[Code]
function IsModuleLoaded(modulename: AnsiString ):  Boolean;
external 'IsModuleLoaded@files:psvince.dll stdcall';
 
               
2、PSVince控件在64位系統(Windows 7/Server 2008/Server 2012)下無法檢測到進程,使用下面的函數可以解決。
 
                
function IsAppRunning(const FileName : string): Boolean;
var
    FSWbemLocator: Variant;
    FWMIService   : Variant;
    FWbemObjectSet: Variant;
begin
    Result := false;
    try
      FSWbemLocator := CreateOleObject('WBEMScripting.SWBEMLocator');
      FWMIService := FSWbemLocator.ConnectServer('', 'root\CIMV2', '', '');
      FWbemObjectSet := FWMIService.ExecQuery(Format('SELECT Name FROM Win32_Process Where Name="%s"',[FileName]));
      Result := (FWbemObjectSet.Count > 0);
      FWbemObjectSet := Unassigned;
      FWMIService := Unassigned;
      FSWbemLocator := Unassigned;
    except
      if (IsModuleLoaded(FileName)) then
        begin
          Result := false;
        end
      else
        begin
          Result := true;
        end
      end;
end;
這里,有可能存在異常:Exception: SWbemLocator:依賴服務或組件無法啟動
解決辦法參照如下步驟:
 
                
1.在命令提示行運行以下命令:
    cd /d %windir%\system32\wbem 
    rename Repository Rep_bak 
2.建一個.bat批處理文件並運行,內容如下: 
    Mofcomp C:\WINDOWS\system32\WBEM\cimwin32.mof
    Mofcomp C:\WINDOWS\system32\WBEM\cimwin32.mfl
    Mofcomp C:\WINDOWS\system32\WBEM\system.mof
    Mofcomp C:\WINDOWS\system32\WBEM\wmipcima.mof
    Mofcomp C:\WINDOWS\system32\WBEM\wmipcima.mfl
3.在命令提示行運行以下命令:
    cd /d %windir%\system32\wbem 
    for %i in (*.mof,*.mfl) do Mofcomp %i 
4.重新注冊 WMI 組件,在命令提示行運行以下命令:
    cd /d %windir%\system32\wbem 
    for %i in (*.dll) do RegSvr32 -s %i 
    for %i in (*.exe) do %i /RegServer 
 
                
//安裝,並在安裝前檢測程序是否在運行,如果運行先結束進程
function InitializeSetup(): Boolean;
begin
  Result := true;
  if  IsAppRunning('{#MyAppExeName}') then
  begin
    if MsgBox('安裝程序檢測到 {#MyAppName} 正在運行!'#13''#13'單擊“是”按鈕關閉程序並繼續安裝;'#13''#13'單擊“否”按鈕退出安裝!', mbConfirmation, MB_YESNO) = IDYES then
    begin
      TaskKillProcessByName('{#MyAppExeName}');
      Result:= true;
    end
    else
      Result:= false;
  end;
end;
//卸載,與安裝類似
 
               
function InitializeUninstall(): Boolean;
  begin
    Result:= true;
    if  IsAppRunning('{#MyAppExeName}') then
    begin
      if MsgBox('卸載程序檢測到 {#MyAppName} 正在運行!'#13''#13'單擊“是”按鈕關閉程序並繼續卸載;'#13''#13'單擊“否”按鈕退出卸載!', mbConfirmation, MB_YESNO) = IDYES then
      begin
        TaskKillProcessByName('{#MyAppExeName}');
        Result:= true;
      end
      else
        Result:= false;
    end;
  end;

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM