场景是我们编写了一个控制台应用程序,我们想在Inno Setup期间调用它并读取其输出。与this problem相比,有必要从Inno Setup读取此输出,而另一个程序仍在运行。输出应包含runnig应用程序的进度信息(double或int值),我们希望使用ProgressGauge在Inno中显示。该应用程序是一个用C#编写的简单可执行文件,可以运行几秒到几分钟。
这是否可行,如果是,可以在不冻结Inno Setup的GUI的情况下完成(因为应用程序可能需要一些时间)?
答案 0 :(得分:1)
TLama指向progress bar messages
我能够解决问题。
首先我需要将Inno的进度条句柄传递给我的C#app。为此我创建了一个函数,它将int指针作为字符串返回
function GetProgressHandle(Param: String): String;
begin
Result := Format('%d',[WizardForm.ProgressGauge.Handle]);
end;
并在调用我的应用时在运行部分中使用它:
[Run]
Filename: "{app}\myApp.exe"; Parameters: "{code:GetProgressHandle}"; ....
在C#中,我从控制台参数中读取了int指针并使用它来创建IntPtr
:
IntPtr pointer = new IntPtr(Int32.Parse(args[0]));
要将消息发送到进度条,我导入了user32.dll并重新定义了所需的常量,通常可以在commctrl.h中找到:
[DllImport("user32.dll")]
public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
public const uint PBM_SETRANGE = 0x401;
public const uint PBM_SETPOS = 0x402;
最后,我可以将进度条的范围从0设置为 max ,将特定位置 pos 设置为
PostMessage(pointer, PBM_SETRANGE, (IntPtr)0, (IntPtr)(max << 16));
PostMessage(pointer, PBM_SETPOS, (IntPtr)pos, (IntPtr)0);
注意:更改进度条位置似乎不会立即更新Inno设置窗口。我通过每500毫秒增加位置来测试它,但是那里存在明显的差异(暂停在大约0.2-0.8毫秒的范围内)。对于我的情况,更改进度条的准确时间并不重要,但我认为Inno Setup窗口可以以类似的方式更新(具有特定句柄和不同的消息常量),以满足那些需要它的人。 / p>