Installation 使Inno安装程序向主安装程序报告其安装进度状态

Installation 使Inno安装程序向主安装程序报告其安装进度状态,installation,progress-bar,inno-setup,ipc,Installation,Progress Bar,Inno Setup,Ipc,我目前有两个Inno安装程序安装程序。我需要其中一个将其作为子安装程序的状态报告给另一个安装程序,即使它使用VERYSILENT命令运行 我需要它在我的主安装程序中根据子安装程序的安装进度显示进度条,因为我不想要任何无限(字幕)进度条 我还读到了关于。如何在Inno设置源代码中添加泵等通信功能?有什么开始的建议吗 提前谢谢。我认为您不需要为此编写花哨的IPC代码。只需通过临时文件交换信息 子安装程序代码: [代码] 函数设置计时器( Wnd:LongWord;IDEvent,Elapse:Lon

我目前有两个Inno安装程序安装程序。我需要其中一个将其作为子安装程序的状态报告给另一个安装程序,即使它使用
VERYSILENT
命令运行

我需要它在我的主安装程序中根据子安装程序的安装进度显示进度条,因为我不想要任何无限(字幕)进度条

我还读到了关于。如何在Inno设置源代码中添加泵等通信功能?有什么开始的建议吗


提前谢谢。

我认为您不需要为此编写花哨的IPC代码。只需通过临时文件交换信息

子安装程序代码:

[代码]
函数设置计时器(
Wnd:LongWord;IDEvent,Elapse:LongWord;TimerFunc:LongWord):LongWord;
外部的SetTimer@user32.dllstdcall';
变量
ProgressFileName:string;
进度:整数;
程序报告ProgressProc(
H:LongWord;Msg:LongWord;Event:LongWord;Time:LongWord);
变量
进度:整数;
开始
尝试
进展:=
(WizardForm.ProgressGauge.Position*100)div WizardForm.ProgressGauge.Max;
如果有进展,那么
开始
如果不保存StringToFile(ProgressFileName、IntToStr(Progress)、False),则
开始
日志(格式('未能保存进度%d',[进度]);
结束
其他的
开始
日志(格式('Saved progress%d',[progress]);
进度:=进度;
结束;
结束;
除了
日志(“异常保存进度”);
结束;
结束;
过程初始化Wizard();
开始
{使用/progress=switch运行时,将向该文件报告进度}
ProgressFileName:=ExpandConstant(“{param:progress}”);
如果文件名为“”,则
开始
日志(格式('将把进度写入:%s',[ProgressFileName]);
进度:=-1;
SetTimer(0,0250,CreateCallback(@ReportProgressProc));
结束;
结束;
主安装程序代码:

#定义ChildInstaller“mysetup.exe”
[档案]
资料来源:{#ChildInstaller};标志:dontcopy
[守则]
函数设置计时器(
Wnd:LongWord;IDEvent,Elapse:LongWord;TimerFunc:LongWord):LongWord;
外部的SetTimer@user32.dllstdcall';
函数KillTimer(hWnd:LongWord;uIDEvent:LongWord):BOOL;
外部的KillTimer@user32.dllstdcall';
变量
ProgressPage:TOutputProgressWizardPage;
ProgressFileName:string;
过程UpdateProgressProc(
H:LongWord;Msg:LongWord;Event:LongWord;Time:LongWord);
变量
S:翻译;
进度:整数;
开始
尝试
如果未加载StringFromFile(ProgressFileName,S),则
开始
日志(格式('从文件%s读取进度失败',[ProgressFileName]);
结束
其他的
开始
进度:=strotintdef(S,-1);
如果(进度<0)或(进度>100),则
开始
日志(格式('Read invalid progress%s',[s]);
结束
其他的
开始
日志(格式('读取进度%d',[进度]);
进度页面。设置进度(进度,100);
结束;
结束;
除了
日志(“异常更新进度”);
结束;
结束;
儿童程序;
变量
ChildInstallerPath:字符串;
ChildInstallerParams:字符串;
定时器:长字;
InstallError:字符串;
结果代码:整数;
开始
ExtractTemporaryFile(“{#ChildInstaller}”);
ProgressPage:=CreateOutputProgressPage('正在运行的子安装程序','');
ProgressPage.SetProgress(01100);
ProgressPage.Show;
尝试
Timer:=SetTimer(0,0250,CreateCallback(@UpdateProgressProc));
ChildInstallerPath:=ExpandConstant('{tmp}\{#ChildInstaller}');
ProgressFileName:=ExpandConstant('{tmp}\progress.txt');
日志(格式('ProgressFileName',预期进度为%s');
ChildInstallerParams:=格式('/verysilent/progress=“%s”,[ProgressFileName]);
如果未执行(ChildInstallerPath、ChildInstallerParams、、SW_SHOW、,
EWWAIT未过滤,结果代码)然后
开始
InstallError:=“无法启动子安装程序”;
结束
其他的
如果结果代码为0,则
开始
InstallError:=格式('子安装程序失败,代码为%d',[ResultCode]);
结束;
最后
{清理}
KillTimer(0,Timer);
进行页面隐藏;
删除文件(ProgressFileName);
结束;
如果安装错误为“”,则
开始
{显示TOutputProgressWizardPage时RaiseException无法正常工作}
RaiseException(InstallError);
结束;
结束;
您可以像下面这样使用
InstallChild
,也可以在安装过程的任何其他位置使用:

函数NextButtonClick(CurPageID:Integer):布尔;
开始
结果:=真;
如果CurPageID=wpReady,则
开始
尝试
儿童;
除了
MsgBox(GetExceptionMessage,mbError,MB_OK);
结果:=假;
结束;
结束;
结束;
另一个好的解决方案是使用。有关示例,请参见我对的回答


对于,您需要Inno设置6。如果您坚持使用Inno Setup 5,则可以使用库中的
WrapCallback
函数


最好使用
TFileStream
而不是
LoadStringFromFile
SaveStringToFile
TFileStream
支持读取共享。使用
LoadStringFromFile
SaveStringToFile
,如果双方同时尝试读写,则进度报告有时可能会暂时失败


这显示了子安装程序和主安装程序的进度链接方式(如果子安装程序不是使用
/verysilent
开关运行,而是仅使用
/silent
开关运行):


如果需要使用独立进度条,可以使用以下主安装程序代码:

#定义ChildInstaller“mysetup.exe”
[档案]
资料来源:{#ChildInstaller};标志:dontcopy
[守则]
函数设置计时器(
Wnd:LongWord;IDEvent,Elapse:LongWord;TimerFunc:LongWord):LongWord;
前任