|
I have a .Net Windows service. I want to create an installer to install that windows service. Basically, it has to do the following:
Also, I want to provide an uninstaller which runs the following command:
How to do these using Inno Setup? |
|||||
|
|
You don't need Here is the way I'm doing it in my application:
Basically you can have your service to install/uninstall on its own by using Then it's just matter of adding into your InnoSetup script something like this:
|
分類:
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;
判斷所選安裝目錄中原版主程序是否存在:
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;
顏色:
clBlack(黑色),clMaroon(暗紅),clGreen(綠色),clOlive(橄欖綠),clNavy(深藍),clPurple(紫色),clTeal(深青),clGray(灰色),clSilver(淺灰),clRed(紅色),clLime(淺綠),clYellow(黃色),clBlue(藍色),clFuchsia(紫紅),clAqua(青綠),clWhite(白色)。te(白色)。
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);
------------------------------------------------------------------------
算不上原創,可也花費了很多時間心血查資料、整理、調試
標簽: innoinno打包issisapprunningpsvince.dll |
分類: 編程 |
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;
