该文只是对调用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
