如何阅读自定义操作';WiX中的可执行输出?

如何阅读自定义操作';WiX中的可执行输出?,wix,windows-installer,wix3.5,custom-action,Wix,Windows Installer,Wix3.5,Custom Action,我正在WiX中制作MSI安装程序。在安装过程中,我希望从运行一个可执行文件,并获取其标准输出(而不是返回代码),以便以后在安装过程中使用(假定是使用元素) 如何在WiX(3.5)中实现它?我将此代码用于类似的任务(它是一个C#DTF自定义操作): 这被称为“屏幕抓取”,虽然从技术上讲,可以创建基础结构来运行进程外的EXE,抓取其输出,然后将数据封送回MSI上下文,但它永远都不是一个健壮的解决方案 一个更好的解决方案是了解EXE的功能以及它是如何实现的。然后编写一个C + o C++的自定义操作,

我正在WiX中制作MSI安装程序。在安装过程中,我希望从运行一个可执行文件,并获取其标准输出(而不是返回代码),以便以后在安装过程中使用(假定是使用元素)


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

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

这被称为“屏幕抓取”,虽然从技术上讲,可以创建基础结构来运行进程外的EXE,抓取其输出,然后将数据封送回MSI上下文,但它永远都不是一个健壮的解决方案


一个更好的解决方案是了解EXE的功能以及它是如何实现的。然后编写一个C + o C++的自定义操作,运行过程中访问MSI句柄,这样你就可以完成工作并设置需要设置的属性。

你的意思是你的自定义动作调用一些exe,它写在控制台上,你想抓取输出吗?严,是的,这就是我的意思。所以我应该创建一个自定义操作来执行可执行文件并获取其控制台输出。看起来是个不错的开始,但是在安装过程中如何访问输出(在属性或变量中)?在我的例子中没有UI(静默安装),所以我不打算显示抓取的输出,而是将其用于进一步处理,例如条件中的参数或其他cusom操作。这是我在WiX中的第一步,很抱歉我的重要性。标记为//的块可能会对字符串进行一些解析,然后执行session[“SOMEPROPERTY”]=SomeParsedStrings之类的操作,但即使可能,我也不推荐这种方法。这将增加安装程序的脆弱性。感谢您的洞察力,但这并不是我问题的真正解决方案。控制台应用程序是由第三方提供的,我只需要使用它并依赖它的输出。逆向工程和重写现有的应用程序似乎没有那么健壮,它非常健壮。这并不容易。您正在创建一个依赖于第三方EXE的模式,并将其注入安装程序。如果它失败了,他们不会责怪第三方依赖,他们会责怪你的安装程序。+1,@Chris,谢谢你的批评。我明白你的意思,我同意如果你依赖第三方EXE可能会很危险。但是如果这是你自己的效用,你认为合适吗?假设您已经使用该实用程序很长一段时间了,测试已经完全覆盖了它,并证明它工作得足够稳定。仅仅抓住它的输出而不是适应自定义操作不是更好吗?这可能意味着复制了您已有的代码,并且由于复制/粘贴而引入了新问题……我想说,如果这是您自己的实用程序,那么代码应该分解为EXE和DLL。DLL公开的函数/方法可以被自定义操作使用。现在您有一个CA客户端和一个EXE客户端,但核心逻辑不重复。这样,您就可以通过编程方式访问逻辑,并进行完整的错误处理和日志记录。不需要代码复制。我有一个类似的问题,除了我的可执行文件返回一个字符串。我如何在wix变量中捕获它?
// 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();