0

ファイルを MSI からフォルダーに抽出する必要がありますが、ファイルのディレクトリ構造をすべて C# アプリケーション内から変更する必要があります (つまり、管理者によるインストールや MSI の他のインストールを実行しないでください)。概念的には、MSI の組み込みキャブを選択したフォルダーに「解凍」したいと考えています。抽出を行うために、WiX 3.6 DTF ライブラリを使用していますが、フォルダー構造を変更する方法を特定できません。

したがって、たとえば、MSI インストーラーを実行した場合、「Component1」のターゲット フォルダーは になりますが、抽出アプリケーションの実行時に、できればディレクトリ パスを変更して、c:\Program Files(x86)\Company Name\Demo Product Installer\Component1\それを に変更したいと思います (以下を参照)。 .c:\SomeOtherPlace\Demo Product Installer\Component1\APPLICATIONFOLDER

MSI の場合、ディレクトリ構造を次のように定義しました。

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

次に、ファイルを抽出する必要があるコードで、次のようにしました。

var msiFilePath = "myInstallerFile.msi";
var targetFolder = @"c:\SomeOtherPlace\";
using (var msiPackage = new InstallPackage(msiFilePath, DatabaseOpenMode.ReadOnly))
{
    msiPackage.WorkingDirectory = targetFolder;

    var dirMapping = msiPackage.Directories;    
    if (dirMapping.ContainsKey("APPLICATIONFOLDER"))                    
    {
        //This doesn't work, but represents what I hope to do:
        var oldInstallPath = dirMapping["APPLICATIONFOLDER"];                        
        oldInstallPath.TargetPath = targetFolder;                   
    }

    msiPackage.UpdateDirectories();                    
    msiPackage.ExtractFiles();                    
    msiPackage.Close();
}

DTF オブジェクトを使用して実行時にこのようなフォルダー構造を変更する方法はありますか? 事後にファイルを移動するだけでよいことはわかっていますが、この方法で移動できれば、はるかにクリーンになります。

4

2 に答える 2

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 に変更したことに注意してください。

もちろん、フォルダー構造にさらに高度な変更を加えたい場合は、ディレクトリ テーブルから追加のレコードを変更/挿入/削除する必要があります。(参照については、 http://msdn.microsoft.com/en-us/library/windows/desktop/aa368295(v=vs.85 ).aspxを参照してください)

于 2012-10-10T19:34:39.767 に答える