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