我目前正在使用WiX / Burn Managed Bootstrapper应用程序,无法弄清楚如何获取有效负载(MSI)的本地路径。
我让用户选择要在我的自定义用户界面中安装哪些应用程序,并且我想不显示缺少MSI的应用程序。我还需要在MSI的数据库中查看信息。
我知道我可以通过处理“ResolveSource”确定丢失的有效负载,但直到安装应用程序之前才会发生。
我首先对BootstrapperApplicationData.xml文件进行反序列化,因此我可以获得有关可能安装哪些MSI的信息,但它仍无法帮助我确定MSI的来源。
有谁知道如何确定有效载荷的本地路径?
编辑:以下是我引用所有安装程序的示例:
<MsiPackage Id="AppName"
SourceFile="$(var.ProjectName.TargetDir)ProjectName.msi"
Name="MSI\ProjectName.msi"
Compressed="no"/>
答案 0 :(得分:1)
在cache.cpp中的GetLastUsedSourceFolder
函数中,您可以看到引擎从WixBundleLastUsedSource
变量获取源文件夹,以及WixBundleOriginalSource
变量的父目录WixBundleLastUsedSource
未设置。
您可以将此与BootstrapperApplicationData.xml文件中Name
元素的WixPayloadProperties
属性一起使用,以预先确定引擎在哪里查找有效负载。请注意,引擎实际上会首先查看缓存。
答案 1 :(得分:1)
MSI文件嵌入到.exe文件中,直到安装应用程序之前才从包中提取,这与ResolveSource
事件触发时相对应。但是,如果确实想要获取此信息,您可以自己以编程方式提取MSI文件,并使用WiX DTF库(WiX安装的/ bin文件夹中的wix.dll)检查它们。 / p>
using Microsoft.Tools.WindowsInstallerXml;
private void ExtractEmbeddedMsiInstallers()
{
var tmpFolder = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
var bundlePath = Engine.StringVariables["WixBundleOriginalSource"];
Unbinder unbinder = null;
try
{
unbinder = new Unbinder();
//The next line will extract the MSIs into the tmpFolder in a subfolder named "AttachedContainer"
unbinder.Unbind(bundlePath, OutputType.Bundle, tmpFolder);
}
finally
{
if (null != unbinder)
unbinder.DeleteTempFiles();
}
}
您还提到需要检查MSI数据库中的数据。以下是如何执行此操作的示例:
using (var database = new InstallPackage(msiFilePath, DatabaseOpenMode.Transact) { WorkingDirectory = _someTempFolder })
{
if (database.Tables.Contains("CustomAction"))
{
using (View view = database.OpenView("SELECT `Action`, `Type`, `Source`, `Target` FROM `CustomAction`"))
{
view.Execute();
foreach (Record rowRecord in view)
using (rowRecord)
{
var actionName = rowRecord.GetString(1);
var actionType = rowRecord.GetInteger(2);
var binaryName = rowRecord.GetString(3);
var methodName = rowRecord.GetString(4);
//Do something with the values
}
}
}
}