4

Nant 0.92 を使用 (以前は 0.85 で同じ結果)

msbuildを呼び出した後、NAnt で削除タスクを呼び出して、.dll ファイルを除くすべてのファイルを削除しようとしています(以下のスクリプトを参照してください。「ビルド」ターゲットで削除を参照しています)。削除タスクが実行されていないようです。

最初の削除タスクは正常に機能し、期待どおりに動作して、指定されたビルド ディレクトリからすべてのファイルを削除します。ただし、コンパイル後の 2 番目の削除タスクは機能しません。

すべてを削除して(excludeタグを使用せずに)、failonerrorverboseを明示的にtrueに設定してみました。これらのどれも違いはありません。また、msbuild の何かが削除に間に合うようにファイルを解放していない場合に備えて、スリープを使用して削除タスクの前にプロセスを停止しようとしました。削除を別のターゲットに入れてみましたが、まだうまくいきません。

このコマンドは明らかにmsbuildを呼び出す前に機能し、 msbuild出力ターゲット以外のディレクトリから削除しようとすると (つまり、出力ファイルをコピーしてから関連ファイルを削除する)、 msbuild 後に機能します。

これはバグであるには根本的な問題であると確信していますが、とにかく質問したいと思いました。もちろん、ファイルを別の場所にコピーし、不要なものを削除してから適切に移動するという回避策を使用しますが、これについては興味があります。

この動作が設計によるものでない限り (NAnt のドキュメントにはそれを示唆するものは何も見つかりませんが)、おそらく msbuild プロセスは NAnt プロセスが完了するまで出力ファイルをロックしているのではないでしょうか? これは私の最善の推測です。さらなる洞察をいただければ幸いです。

編集: また、msbuild の \OutputPath スイッチを明示的に設定すると、同じ問題は発生しません。デフォルトのOutputPathが使用されている場合に問題が発生するように見えるだけです。

NAnt ビルド ファイル:

<?xml version="1.0" encoding="utf-8" ?>
<project name="Reports.TestBench.PreBuild" default="postbuild.cleanup" basedir="." xmlns="http://nant.sourceforge.net/release/0.86-beta1/nant.xsd">
    <property name="nant.settings.currentframework" value="net-4.0" />
    <property name="project.StandardReports" value="${project::get-base-directory()}\Reports.StandardReports\Palladium.Reports.StandardReports.csproj" />
    <property name="output.Dir" value="${project::get-base-directory()}\bin\debug\"/>
    <property name="build.Type" value="debug"/>

    <!--Deletes the pre-existing build files-->
    <target name="clean">
        <delete>
          <fileset basedir="${output.Dir}">
            <include name="*.*" />  
          </fileset>
        </delete>
    </target>

    <!--Builds the projects to the specified build directory-->
    <target name="build" depends="clean" description="Build the Palladium Reports Standard Reports application">
        <msbuild project="${project.StandardReports}">
            <arg value="/p:Configuration=${build.Type}" />
            <!--arg value="/p:OutputPath=${path::get-full-path(buildDir.Client)}\Reports" /-->
            <arg value="/t:Rebuild" />
        </msbuild>

        <delete failonerror="true" verbose="true">
          <fileset basedir="${output.Dir}">
            <include name="*.*" />
            <exclude name="Palladium.Reports.StandardReports.dll" />
          </fileset>
        </delete>
    </target>
</project>

それ以上のメッセージなしでビルドの成功を示す NAnt 出力の概要:

  [msbuild] Build succeeded.
  [msbuild]     0 Warning(s)
  [msbuild]     0 Error(s)
  [msbuild] 
  [msbuild] Time Elapsed 00:00:03.19

BUILD SUCCEEDED

Total time: 3.5 seconds.
4

1 に答える 1

0

NAnt ソース コードを突っ込んでみてください。ほとんどの場合、msbuildタスクは MSBuild エンジンを作成し、後でファイルを強制的に閉じません。MSDNのドキュメントを見ても、それを行う方法が実際にはわかりません.MSBuildコンストラクトにはDispose()機能がありません. などのクラスにはファイナライザーがあるProjectInstanceため、アプリケーション ドメインで実行し、後でドメイン全体を閉じることでファイル ハンドルを強制的に解放することができます。これはかなりの作業です。

于 2012-10-10T12:37:26.900 に答える