我需要将文件从MSI解压缩到一个文件夹中,但是改变文件的目录结构,所有这些都来自C#应用程序(即:不通过管理员安装,或任何其他MSI安装)。从概念上讲,我想将MSI的嵌入式驾驶室“解压缩”到我选择的文件夹中。要进行提取,我使用的是WiX 3.6 DTF库,但无法确定如何更改文件夹结构。
因此,例如,如果我运行MSI安装程序,“Component1”的目标文件夹将是c:\Program Files(x86)\Company Name\Demo Product Installer\Component1\
,但在我的提取器应用程序的运行时,我想将更改添加到{{1最好通过更改c:\SomeOtherPlace\Demo Product Installer\Component1\
目录路径(见下文)。
对于MSI,我已经定义了这样的目录结构:
APPLICATIONFOLDER
然后,在需要提取文件的代码中,我已经完成了这个:
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="APPLICATIONFOLDER" Name="Company Name">
<Directory Id="ProductFolder" Name="Demo Product Installer">
<Directory Id="Cmp1Folder" Name="Component1" />
<Directory Id="Cmp2Folder" Name="Component2" />
</Directory>
</Directory>
</Directory>
</Directory>
</Fragment>
有没有办法在运行时使用DTF对象修改这样的文件夹结构?我知道我可以在事后移动文件,但如果我能这样做,它会更清洁。
答案 0 :(得分:1)
提取后移动文件肯定会更有效。您可以将数据库复制到临时文件,打开它进行编辑并操作表,然后再将其作为包打开并解压缩。您也可以在表(临时表)的内存更新中执行此操作,而无需提交到磁盘。
答案 1 :(得分:1)
根据Chirtopher的答案,根据提示(“你可能会在表格的内存更新中做到这一点......”),我找到了一个可行的解决方案:
var msiFilePath = "myInstallerFile.msi";
var targetFolder = @"c:\SomeOtherPlace\";
using (var msiPackage = new InstallPackage(msiFilePath, DatabaseOpenMode.Transact))
{
msiPackage.WorkingDirectory = targetFolder;
var dirMapping = msiPackage.Directories;
if (dirMapping.ContainsKey("APPLICATIONFOLDER"))
{
//**** Modified code starts here ***//
// Changed the "APPLICATIONFOLDER" entry from "Company Name" to ".",
// which is a special value to denote the extracted folder.
var record = new Record(".", "APPLICATIONFOLDER");
msiPackage.Execute("UPDATE `Directory` SET `DefaultDir` = ? WHERE `Directory` = ?", record);
//**** Modified code ends here ***//
}
msiPackage.UpdateDirectories();
msiPackage.ExtractFiles();
//Close **without** calling Commit() to ensure changes are not persisted
msiPackage.Close();
}
请注意,我还将DatabaseOpenMode更改为Transact。
当然,如果您想对文件夹结构进行更高级的更改,则必须从Directory表中修改/插入/删除其他记录。 (参见http://msdn.microsoft.com/en-us/library/windows/desktop/aa368295(v=vs.85).aspx)