Azureの小ネタ (改)

~Azureネタを中心に、色々とその他の技術的なことなどを~

TransformXmlとコンフリクトしてアセンブリリダイレクトが有効にならない

Consoleプロジェクトで最終的なConfigファイルにアセンブリリダイレクトが自動生成されなくて悩んでいたんだけどその覚え書き。

github.com

Issueとしてはいくつか上がっているのだけれど、この中で、

https://github.com/Microsoft/msbuild/issues/1310#issuecomment-429878218 のコメントで、TransformXml使ってるとApp.Configファイルがコンフリクトしてうまくいかないよと言及が。

よくよく自分のProjectみるとApp.configファァイルの切り替えに、以下の拡張(もしくはそれに類似したcsprojの手動修正)を使っていたですが、どうもそれが原因です。

marketplace.visualstudio.com

動作順序としては、

  1. GenerateBindingRedirects (App.Config -> Hoge.exe.Configへ生成)
  2. TransformXml (App.Config -> Hoge.exe.Config へ生成)

という形なので、間にファイルコピーを挟めばうまくいくかなと言うことで以下。前者のTargetでいったんHoge.exe.bind.config と名前を変えてCopyして、後続のTransformXmlでは、それを入力ファイルとすることで回避。

  <Target Name="App_config_Preprocess" AfterTargets="GenerateBindingRedirects">
    <Copy SourceFiles="$(IntermediateOutputPath)$(TargetFileName).config" DestinationFiles="$(IntermediateOutputPath)$(TargetFileName).bind.config" />
  </Target>

  <Target Name="App_config_AfterCompile" AfterTargets="AfterCompile" Condition="Exists('App.$(Configuration).config')">
    <!--Generate transformed app config in the intermediate directory-->
    <TransformXml Source="$(IntermediateOutputPath)$(TargetFileName).bind.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="App.$(Configuration).config" />
    <!--Force build process to use the transformed configuration file from now on.-->
    <ItemGroup>
      <AppConfigWithTargetPath Remove="$(IntermediateOutputPath)$(TargetFileName).bind.config" />
      <AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config">
        <TargetPath>$(TargetFileName).config</TargetPath>
      </AppConfigWithTargetPath>
    </ItemGroup>
  </Target>

とりあえずアドホックな対処だけどちゃんと生成されているぽいので様子見。