28

ORM レイヤーをビルドするカスタム MSBuild タスクを開発しており、それをプロジェクトで使用しています。私は、MSBuild タスク DLL を保持して手放さないという Visual Studio の動作に妨げられています。

このようにソリューションを整理したいと思います。

My Solution
 |
 +- (1) ORM Layer Custom Task Project
 |  |
 |  +- BuildOrmLayerTask.cs     // here's my task
 |  
 +- (2) Business Logic Project  // and here's the project that uses it.
    |
    +- <UsingTask TaskName="BuildOrmLayerTask" AssemblyFile="$(TaskAssembly)" />

ただし、プロジェクト (2) がビルドされると、プロジェクト (1) のアセンブリにロックされます。そのため、ソリューションを閉じて再度開くことなく、プロジェクト (1) を再度ビルドすることはできません。

カスタム ビルド タスクが Visual Studio によってロックされないように整理する方法はありますか?

4

3 に答える 3

26

(編集: msbuild に関する本を文字通り書いたSayed Ibrahim Hashimiは、より良いアプローチのためにAppDomainIsolatedTaskクラスを提案しています)

私はこれを自分で解決することができました...

Microsoft の MSBuild 開発者の 1 人であるDan Moseley による次のフォーラム投稿を見つけました。

やあ、

残念ながら、これは MSBuild がタスク アセンブリをプライマリ アプリケーション ドメインに読み込むためです。CLR では、アセンブリが appdomain からアンロードされることは許可されていません。これにより、重要な最適化が可能になるからです。

私が提案する唯一の回避策は、tomsbuild.exe を呼び出して、タスクを使用するプロジェクトをビルドすることです。これを行うには、MSBuild.exe <> を VS の外部ツールとして作成します。

msbuild のDan
開発者
DanMoseley - MSFT

したがって、ロックを停止するには、新しい MSBuild.exe プロセスを生成する必要があるようです。MSBuild が実行されると、Visual Studio のプライマリ アプリ ドメインにタスクが読み込まれ、決してアンロードできないためです。

  • 「ビルド」ターゲットをオーバーライドし、カスタム アクションを実行する新しい MSBuild プロジェクト (.csproj など) を作成します。

    <!-- fragment of Prebuild.csproj -->   
    <Target Name="Build">   
         <BuildOrmLayerTask Repository="$(Repository)" />   
    </Target>
    
  • 必要に応じて Visual Studio に追加しますが、Configuration Manager を使用して、どの構成にも組み込まれていないことを確認してください。ビルドではなく、VSにソース管理などを任せてください。

  • に依存するプロジェクトの .csproj ファイルを編集しますPrebuild.csprojBeforeBuildタスクを使用して MSBuild を呼び出すターゲットを追加しExecます。これにより新しいプロセスが開始され、そのプロセスが終了すると、ファイルのロックが解除されます。例;

    <PropertyGroup>   
         <PrebuildProject>$(SolutionDir)Prebuild\Prebuild.csproj</PrebuildProject>   
    </PropertyGroup>   
    <Target Name="BeforeBuild">   
         <Exec Command="msbuild.exe &quot;$(PrebuildProject)&quot;" />   
    </Target>
    

これで、依存プロジェクトをビルドすると、コンパイルを実行する前に新しいプロセスで MSBuild が実行されます。

于 2010-08-04T13:25:31.987 に答える
4

プロジェクト ファイルを編集して、次のプロパティ宣言を含めることはできますか

<PropertyGroup>
    <GenerateResourceNeverLockTypeAssemblies>true</GenerateResourceNeverLockTypeAssemblies>
</PropertyGroup>

それがうまくいくかどうか教えてください。

于 2010-08-04T06:53:20.437 に答える
3

@Al-Muhandis 宛てのコメントで述べたように、カスタム タスクの周りにラッパーを作成して、ラッパーはロックされますが、カスタム タスク DLL はロックされないようにすることが可能です。私は、分離タスクプロジェクトで最初の試みを行いました。バグがある可能性があり、現在のところ VS2008 でのみ動作します。プル リクエストを歓迎します。

MarshalByRefObjectこのプロジェクトのアイデアは、 (おそらく を使用してAppDomainIsolatedTask) から派生したタスクは、リフレクションのためにメイン アプリケーション ドメインに読み込まれるように見えるが、タスクを実行するために新しいアプリケーション ドメインが作成されるという観察に基づいていました。AppDomainIsolatedTaskメイン アプリケーション ドメインへのロードは依然として DLL をロックしているように見えるため、カスタム タスク DLL をロードするタスクから派生した DLL を作成すると便利でした。こうすると、ラッパー DLL はロックされますが、独自のアプリ ドメインで実行されるため、ラッパー タスクの実行ドメインがアンロードされると、カスタム タスク DLL もアンロードされます。この手順により、ビルドの完了後にカスタム タスク DLL がロックされたままになることを回避できます。

于 2014-07-10T19:10:24.340 に答える