該文只是對調用dll來實現一鍵安裝的概述,沒有具體說明dll內部怎樣實現!僅供參考!
1、c++寫的dll中的函數及dll文件截圖
extern "C" { //描述:安裝服務初始化 //參數:pszFileDir插件解壓的所在目錄 bool __stdcall SetupInit(char *pszFileDir); //描述:顯示安裝操作界面 void __stdcall SetupShowMainWnd(); //描述:關閉安裝操作界面 void __stdcall SetupCloseMainwWnd(); //描述:等待用戶選擇是否安裝 //返回值:1:表示進入安裝、2:表示退出安裝 int __stdcall SetupWaitUserAction(); //描述:獲取安裝用戶選擇的路徑 //返回值:返回拷貝的字符串長度 char *__stdcall SetupGetInstallPath(); //描述:設置當前安裝的進度 //參數:nCurProgress 當前安裝的進度值 //參數:nMaxProgress 安裝進度最大值 //返回值:無 void __stdcall SetupSetProgress(int nCurProgress,int nMaxProgress); //描述:等待用戶點擊安裝完成 void __stdcall SetupWaitCompleted(); //顯示一個錯誤提示模態對話框 //參數:psztipTxt 提示的文本 bool __stdcall ShowTipWnd(char *psztipTxt); //描述:安裝服務反初始化 void __stdcall SetupUninit(); //描述:隱藏當前線程所有窗口 void __stdcall HideCurThreadAllWnd(); void __stdcall DeleteFileEx(char *pszFilePath); };
2、申明函數
[Code] function SetupInit(pszFileDir: PAnsiChar):Boolean; external 'SetupInit@files:InstallPlug.dll,DuiLib.dll,Lang.xml,skin.zip stdcall setuponly delayload loadwithalteredsearchpath'; procedure SetupShowMainWnd(); external 'SetupShowMainWnd@files:InstallPlug.dll,DuiLib.dll,Lang.xml,skin.zip stdcall setuponly delayload loadwithalteredsearchpath'; procedure SetupCloseMainwWnd(); external 'SetupCloseMainwWnd@files:InstallPlug.dll,DuiLib.dll,Lang.xml,skin.zip stdcall setuponly delayload loadwithalteredsearchpath'; function SetupWaitUserAction():Integer; external 'SetupWaitUserAction@files:InstallPlug.dll,DuiLib.dll,Lang.xml,skin.zip stdcall setuponly delayload loadwithalteredsearchpath'; function SetupGetInstallPath():PAnsiChar; external 'SetupGetInstallPath@files:InstallPlug.dll,DuiLib.dll,Lang.xml,skin.zip stdcall setuponly delayload loadwithalteredsearchpath'; procedure SetupSetProgress(nCurProgress,nMaxProgress:Integer); external 'SetupSetProgress@files:InstallPlug.dll,DuiLib.dll,Lang.xml,skin.zip stdcall setuponly delayload loadwithalteredsearchpath'; procedure SetupWaitCompleted(); external 'SetupWaitCompleted@files:InstallPlug.dll,DuiLib.dll,Lang.xml,skin.zip stdcall setuponly delayload loadwithalteredsearchpath'; procedure SetupUninit(); external 'SetupUninit@files:InstallPlug.dll,DuiLib.dll,Lang.xml,skin.zip stdcall setuponly delayload loadwithalteredsearchpath'; function ShowTipWnd(psztipTxt:PAnsiChar):Boolean; external 'ShowTipWnd@files:InstallPlug.dll,DuiLib.dll,Lang.xml,skin.zip stdcall setuponly delayload loadwithalteredsearchpath'; procedure HideCurThreadAllWnd(); external 'HideCurThreadAllWnd@files:InstallPlug.dll,DuiLib.dll,Lang.xml,skin.zip stdcall setuponly delayload loadwithalteredsearchpath'; procedure DeleteFileEx(pszFilePath:PAnsiChar); external 'DeleteFileEx@files:InstallPlug.dll,DuiLib.dll,Lang.xml,skin.zip stdcall setuponly delayload loadwithalteredsearchpath'; //全局變量 var RootDestFolder,installparam:string;
概述:
Pascal腳本能調用外部dll(標准Win32 API或者各程序員編寫的dll)中的函數,在調用外部dll中的函數前,需要聲明所調用的函數原型,使用external聲明dll文件,對於一個Pascal描述的函數原型,
例如 function A(B: Integer): Integer;可以有三種方式調用:
方法一:
function A(B: Integer): Integer;
external '< dll中函數名稱> >@< dll文件路徑 >';
方法二:
function A(B: Integer): Integer;
external '< dll中函數名稱> >@< dll文件路徑 > <調用約定>';
方法三:
function A(B: Integer): Integer;
external '<dll中函數名稱>@<dll文件路徑> <調用約定> <選項>';
第一種方法最簡單,這是Pascal腳本的默認調用方法,調用約定為stdcall,絕大部分的調用都是采用這種方式,當然也可以使用其他的調用約定:cdecl、pascal和register
另外:
函數有返回值的,用function;無返回值的,用procedure
3、初始安裝
//初始安裝 function InitializeSetup(): Boolean; var RetValue,RetValue1,RetValue2,RetValue3,RetValue4,version0,IsRunning,installorexit:Integer; mypath,msgboxinfo,tmpintallpath,testpath:string; isintallpath: Boolean; begin installparam := GetMyParam('/VERYSILENT'); //判斷是否是靜默安裝命令 RootDestFolder:=''; //安裝服務初始化 setlength(tmpintallpath,1024); tmpintallpath := ExpandConstant('{tmp}\'); if SetupInit(tmpintallpath) then begin while IsRunning=0 do begin Result :=true; //安裝程序繼續 //**********安裝之前判斷ErrorReport.exe是否正在運行**************** msgboxinfo :=''; Exec('cmd.exe', '/C tasklist|findstr /i "ErrorReport.exe"', '', SW_HIDE,ewWaitUntilTerminated, RetValue3); //0為進程在運行,1為進程沒有運行 if RetValue3=0 then msgboxinfo := msgboxinfo+ 'ErrorReport.exe{n}'; if ShowTipWnd(ExpandConstant('{cm:MyMsgboxinfoInstall}')+msgboxinfo+ExpandConstant('{cm:MyMsgboxinfoInstall2}')) then begin IsRunning :=0; end else begin IsRunning :=1; Result :=false; //安裝程序退出 end; //**********運行一鍵安裝的界面**************** HideCurThreadAllWnd(); //隱藏當前線程所有窗口,為了解決安裝時任務欄顯示inno原來的安裝窗口以及dll寫的一個安裝窗口,兩個安裝窗口同時存在的情況 //installparam為空則表示沒有靜默安裝的命令,表示本次安裝是非靜默安裝,則需要顯示一鍵安裝的界面,按照安裝步驟一步步進行安裝 if installparam='' then begin SetupShowMainWnd(); //顯示安裝操作界面 installorexit := SetupWaitUserAction();//等待用戶選擇是否安裝,返回值:1:表示進入安裝、2:表示退出安裝 if installorexit=1 then begin RootDestFolder:=SetupGetInstallPath(); //獲取安裝用戶選擇的路徑 end else begin SetupCloseMainwWnd(); //關閉安裝操作界面 Result :=false; end //本次安裝是靜默安裝,不顯示任何安裝界面,直接獲取安裝路徑 end else RootDestFolder:=SetupGetInstallPath(); //******************************** end; end end;
4、隱藏inno原來的安裝界面
procedure InitializeWizard(); begin //不顯示邊框,這樣就能達到不會閃兩下了 WizardForm.BorderStyle:=bsNone; end; //不顯示一些特定的安裝界面 function ShouldSkipPage(PageID: Integer): Boolean; begin Result := True end; //改變頁面時隱藏界面窗口 procedure CurPageChanged(CurPageID: Integer); var indexpageid3:Integer; begin //因為安裝過程界面隱藏不了,所以設置窗口寬高為0 WizardForm.ClientWidth := ScaleX(0); WizardForm.ClientHeight := ScaleY(0); //在InnoSetup中,我們很容易用 function ShouldSkipPage(CurPage: Integer): Boolean; 來跳過一些頁面,但是Welcome Page是無法用這個函數來跳過的。如果一定要實現這樣的功能,可以用消息來模擬鼠標按鍵 if CurPageID = wpWelcome then WizardForm.NextButton.OnClick(WizardForm); if CurPageID >= wpInstalling then WizardForm.Visible := False else WizardForm.Visible := True; end;
5、顯示安裝進度
procedure CurInstallProgressChanged(CurProgress, MaxProgress: Integer); begin if installparam='' then SetupSetProgress(CurProgress,MaxProgress); end;
6、程序安裝之前和安裝之后執行操作
procedure CurStepChanged(CurStep: TSetupStep); var IniPath : string; begin if (CurStep=ssInstall) then begin SetLanCode(); end; if (CurStep=ssPostInstall ) then begin if installparam='' then SetupWaitCompleted();//非靜默安裝才需要執行 end; end;
7、反初始化
//反初始化 procedure DeinitializeSetup; begin SetupUninit(); end;
8、其他函數
//獲取安裝參數 function GetMyParam(PName:String):String; var CmdLine : String; CmdLineLen : Integer; i : Integer; begin CmdLineLen:=ParamCount(); for i:=0 to CmdLineLen do begin CmdLine:=ParamStr(i); if CmdLine= PName then begin //CmdLine:=ParamStr(i+1); Result := CmdLine; Exit; end; end; end;
//判斷是否靜默安裝 function IsSilentInstall():Boolean; begin Result := not (installparam ='') ;//installparam 在InitializeSetup中獲取到值了,這里只是進行判斷 end;
//返回真正的安裝路徑 function MyDestDir(SubDir:String):String; begin if SubDir = '' then Result := RootDestFolder else Result := RootDestFolder + '\'+ SubDir; end;
8、定制安裝路徑
[Setup] UninstallDisplayIcon={code:MyDestDir|{#MyRegProductName}\XXX.exe} UninstallFilesDir={code:MyDestDir} [Files] Source: "{#ComonBinDir}\XXX\YYY\*"; DestDir: {code:MyDestDir|{#MyRegProductName}}; Flags: ignoreversion recursesubdirs createallsubdirs Source: "{#ComonBinDir}\XXX\YYY\FMRun64.dll";DestDir: {code:MyDestDir|{#MyRegProductName}}; Flags: ignoreversion; Check:IsWin64 [Icons] Name: "{group}{#MyAppVision}\{cm:MyAppName}{#MyAppVision}"; Filename: {code:MyDestDir|{#MyRegProductName}\{#MyAppExeName}} Name: "{group}{#MyAppVision}\{cm:MyScreenAppName}"; Filename: {code:MyDestDir|{#MyRegScreenProductName}\Screen.exe} Name: "{group}{#MyAppVision}\{cm:UninstallProgram,{cm:MyAppName}}{#MyAppVision}"; Filename: "{uninstallexe}" Name: "{commondesktop}\{cm:MyAppName}{#MyAppVision}"; Filename: {code:MyDestDir|{#MyRegProductName}\{#MyAppExeName}}; Tasks: desktopicon
