该文只是对调用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 &#39;< dll中函数名称> >&#64;< dll文件路径 >&#39;;
方法二&#xff1a;
function A(B: Integer): Integer;
external &#39;< dll中函数名称> >&#64;< dll文件路径 > <调用约定>&#39;;
方法三&#xff1a;
function A(B: Integer): Integer;
external &#39;
第一种方法最简单&#xff0c;这是Pascal脚本的默认调用方法&#xff0c;调用约定为stdcall&#xff0c;绝大部分的调用都是采用这种方式&#xff0c;当然也可以使用其他的调用约定&#xff1a;cdecl、pascal和register
另外&#xff1a;
函数有返回值的&#xff0c;用function&#xff1b;无返回值的&#xff0c;用procedure
3、初始安装
//初始安装
function InitializeSetup(): Boolean;
var
RetValue,RetValue1,RetValue2,RetValue3,RetValue4,version0,IsRunning,installorexit:Integer;
mypath,msgboxinfo,tmpintallpath,testpath:string;
isintallpath: Boolean;
begin
installparam :&#61; GetMyParam(&#39;/VERYSILENT&#39;); //判断是否是静默安装命令
RootDestFolder:&#61;&#39;&#39;;
//安装服务初始化
setlength(tmpintallpath,1024);
tmpintallpath :&#61; ExpandConstant(&#39;{tmp}\&#39;);
if SetupInit(tmpintallpath) then
begin
while IsRunning&#61;0 do
begin Result :&#61;true; //安装程序继续 //**********安装之前判断ErrorReport.exe是否正在运行**************** msgboxinfo :&#61;&#39;&#39;; Exec(&#39;cmd.exe&#39;, &#39;/C tasklist|findstr /i "ErrorReport.exe"&#39;, &#39;&#39;, SW_HIDE,ewWaitUntilTerminated, RetValue3); //0为进程在运行&#xff0c;1为进程没有运行 if RetValue3&#61;0 then msgboxinfo :&#61; msgboxinfo&#43; &#39;ErrorReport.exe{n}&#39;; if ShowTipWnd(ExpandConstant(&#39;{cm:MyMsgboxinfoInstall}&#39;)&#43;msgboxinfo&#43;ExpandConstant(&#39;{cm:MyMsgboxinfoInstall2}&#39;)) then begin IsRunning :&#61;0; end else begin IsRunning :&#61;1; Result :&#61;false; //安装程序退出 end; //**********运行一键安装的界面**************** HideCurThreadAllWnd(); //隐藏当前线程所有窗口,为了解决安装时任务栏显示inno原来的安装窗口以及dll写的一个安装窗口&#xff0c;两个安装窗口同时存在的情况//installparam为空则表示没有静默安装的命令&#xff0c;表示本次安装是非静默安装&#xff0c;则需要显示一键安装的界面&#xff0c;按照安装步骤一步步进行安装if installparam&#61;&#39;&#39; then begin SetupShowMainWnd(); //显示安装操作界面installorexit :&#61; SetupWaitUserAction();//等待用户选择是否安装&#xff0c;返回值&#xff1a;1:表示进入安装、2:表示退出安装if installorexit&#61;1 then beginRootDestFolder:&#61;SetupGetInstallPath(); //获取安装用户选择的路径end elsebeginSetupCloseMainwWnd(); //关闭安装操作界面 Result :&#61;false; end //本次安装是静默安装&#xff0c;不显示任何安装界面&#xff0c;直接获取安装路径end elseRootDestFolder:&#61;SetupGetInstallPath();//******************************** end;
end
end;
4、隐藏inno原来的安装界面
procedure InitializeWizard();
begin
//不显示边框&#xff0c;这样就能达到不会闪两下了
WizardForm.BorderStyle:&#61;bsNone;
end;//不显示一些特定的安装界面
function ShouldSkipPage(PageID: Integer): Boolean;
begin Result :&#61; True
end;//改变页面时隐藏界面窗口
procedure CurPageChanged(CurPageID: Integer);
var
indexpageid3:Integer;
begin//因为安装过程界面隐藏不了&#xff0c;所以设置窗口宽高为0WizardForm.ClientWidth :&#61; ScaleX(0);WizardForm.ClientHeight :&#61; ScaleY(0);//在InnoSetup中&#xff0c;我们很容易用 function ShouldSkipPage(CurPage: Integer): Boolean; 来跳过一些页面&#xff0c;但是Welcome Page是无法用这个函数来跳过的。如果一定要实现这样的功能&#xff0c;可以用消息来模拟鼠标按键if CurPageID &#61; wpWelcome thenWizardForm.NextButton.OnClick(WizardForm);if CurPageID >&#61; wpInstalling thenWizardForm.Visible :&#61; FalseelseWizardForm.Visible :&#61; True;
end;
5、显示安装进度
procedure CurInstallProgressChanged(CurProgress, MaxProgress: Integer);
begin if installparam&#61;&#39;&#39; then SetupSetProgress(CurProgress,MaxProgress);
end;
6、程序安装之前和安装之后执行操作
procedure CurStepChanged(CurStep: TSetupStep);
varIniPath : string;
beginif (CurStep&#61;ssInstall) then beginSetLanCode();end;if (CurStep&#61;ssPostInstall ) then beginif installparam&#61;&#39;&#39; then SetupWaitCompleted();//非静默安装才需要执行end;
end;
7、反初始化
//反初始化
procedure DeinitializeSetup;
beginSetupUninit();
end;
8、其他函数
//获取安装参数
function GetMyParam(PName:String):String;
var CmdLine : String; CmdLineLen : Integer; i : Integer;
begin CmdLineLen:&#61;ParamCount(); for i:&#61;0 to CmdLineLen do begin CmdLine:&#61;ParamStr(i); if CmdLine&#61; PName then begin //CmdLine:&#61;ParamStr(i&#43;1); Result :&#61; CmdLine; Exit; end; end;
end;
//判断是否静默安装
function IsSilentInstall():Boolean;
beginResult :&#61; not (installparam &#61;&#39;&#39;) ;//installparam 在InitializeSetup中获取到值了&#xff0c;这里只是进行判断
end;
//返回真正的安装路径
function MyDestDir(SubDir:String):String;
beginif SubDir &#61; &#39;&#39; thenResult :&#61; RootDestFolderelseResult :&#61; RootDestFolder &#43; &#39;\&#39;&#43; SubDir;
end;
8、定制安装路径
[Setup]
UninstallDisplayIcon&#61;{code:MyDestDir|{#MyRegProductName}\XXX.exe}
UninstallFilesDir&#61;{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