該文只是對調用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


