1

场景是我们编写了一个控制台应用程序,我们想在 Inno Setup 期间调用它并读取它的输出。与此问题相反,有必要在其他程序仍在运行时从 Inno Setup 读取此输出。输出应包含运行应用程序的进度信息(double 或 int 值),我们希望使用 ProgressGauge 在 Inno 中显示这些信息。该应用程序是一个用 C# 编写的简单可执行文件,可以运行几秒钟到几分钟。

这是否可能,如果可以,是否可以在不冻结 Inno Setup 的 GUI 的情况下完成(因为应用程序可能需要一些时间)?

4

1 回答 1

3

随着 TLama 指向progress bar messages我能够解决问题。

起初我需要将进度条句柄从 Inno 传递到我的 C# 应用程序。为此,我创建了一个函数,它将 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 到最大值以及特定位置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 窗口可以以类似的方式更新(使用特定的句柄和不同的消息常量),以供需要的人使用。

于 2013-09-13T16:56:25.510 回答