如何使用WiX DTF提取MSI时修改文件夹结构

时间:2012-10-09 20:31:48

标签: wix dtf

我需要将文件从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对象修改这样的文件夹结构?我知道我可以在事后移动文件,但如果我能这样做,它会更清洁。

2 个答案:

答案 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