【问题标题】:How can I read custom action's executable output in WiX?如何在 WiX 中读取自定义操作的可执行输出?
【发布时间】:2012-08-19 00:24:48
【问题描述】:

我正在 WiX 中制作 MSI 安装程序。在安装过程中,我想从custom action 运行一个可执行文件并获取其标准输出(不是返回代码)以供以后在安装过程中使用(据说是Property 元素)。

如何在 WiX (3.5) 中实现它?

【问题讨论】:

  • 您的意思是您的自定义操作调用了一些写入控制台的 EXE,并且您想获取该输出?
  • Yan,是的,我就是这个意思。问题已编辑。

标签: wix windows-installer wix3.5 custom-action


【解决方案1】:

我将此代码用于类似的任务(它是 C# DTF 自定义操作):

// your process data
ProcessStartInfo processInfo = new ProcessStartInfo() {
   CreateNoWindow = true,
   LoadUserProfile = true,
   UseShellExecute = false,
   RedirectStandardOutput = true,
   StandardOutputEncoding = Encoding.UTF8,
   ...
};

Process process = new Process();
process.StartInfo = processInfo;
process.OutputDataReceived += (object sender, DataReceivedEventArgs e) =>
  {
     if (!string.IsNullOrEmpty(e.Data) && session != null)
     {
         // HERE GOES THE TRICK!
         Record record = new Record(1);
         record.SetString(1, e.Data);
         session.Message(InstallMessage.ActionData, record);
      }
  };

process.Start();
process.BeginOutputReadLine();
process.WaitForExit();

if (process.ExitCode != 0) {
   throw new Exception("Execution failed (" + processInfo.FileName + " " + processInfo.Arguments + "). Code: " + process.ExitCode);
}

process.Close();

【讨论】:

  • 所以我应该创建一个自定义操作来执行可执行文件并获取其控制台输出。看起来是一个好的开始,但我如何在安装过程中访问输出(在属性或变量中)?在我的情况下没有 UI(静默安装),所以我不会显示抓取的输出,而是将其用于进一步处理,例如。用于条件或其他自定义操作中的参数。这些是我在 WiX 中的第一步,很抱歉我的坚持。
  • 标记为 //here 的块可能会对字符串进行一些解析,然后执行类似 session["SOMEPROPERTY"] = someParsedString 的操作
  • 但我真的不推荐这种方法,即使它是可能的。这会增加安装程序的脆弱性。
【解决方案2】:

这称为“屏幕抓取”,虽然在技术上可以创建基础架构以在进程外运行 EXE,抓取其输出,然后将数据编组回 MSI 上下文,但它永远不会是一个可靠的解决方案。

更好的解决方案是了解 EXE 的作用以及它的作用方式。然后编写一个 C# 或 C++ 自定义操作,该操作在进程中运行并访问 MSI 句柄,以便您可以完成工作并设置您需要设置的属性。

【讨论】:

  • 感谢您的洞察力,但这并不能真正解决我的问题。控制台应用程序由第三方提供,我只需要使用它并依赖它的输出。逆向工程和重写现有应用程序似乎并不那么健壮。
  • 它非常健壮。这不是很EASY。您正在创建一个依赖第三方 EXE 的模式,并将其注入到您的安装程序中。如果它失败(它会),他们不会责怪第三方依赖,他们会责怪你的安装程序。
  • +1,@Chris,感谢您的批评。我明白你的意思,我同意如果你依赖第三方 EXE 可能会很危险。但是,如果它是您自己的实用程序,您认为合适吗?假设您使用该实用程序已经有一段时间了,并且它已被测试完全覆盖并证明它足够稳定。只获取它的输出而不是适应自定义操作不是更好吗?这可能意味着您已经拥有的代码的重复,并且由于复制/粘贴而引入了新问题......
  • 我会说如果它是你自己的实用程序,那么代码应该被分解成一个 EXE 和 DLL。然后,您的自定义操作可以使用 DLL 公开的函数/方法。现在您有一个 CA 客户端和一个 EXE 客户端,但核心逻辑没有重复。然后,这使您可以对具有完整错误处理和日志记录的逻辑进行编程访问。无需重复代码。
  • 我有一个类似的问题,除了我的可执行文件返回一个字符串我如何在 wix 变量中捕获它?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-08
  • 2011-08-05
  • 1970-01-01
  • 2013-06-29
相关资源
最近更新 更多