27

Web アプリケーションを含む複数のプロジェクトを含むソリューションがあります。MSBuild で、Web アプリケーション プロジェクトに対して "WebPublish" ターゲットを実行し、ソリューション内の他のすべてのプロジェクトに対して "既定のターゲット" を実行します。

このMSDNの記事では、コマンドラインを指定して実行できると書かれています

msbuild SlnFolders.sln /t:NotInSlnfolder:Rebuild;NewFolder\InSolutionFolder:Clean

しかし、私はそれを機能させることができませんでした.MSBuildは、「NotInSlnFolder:Rebuild」ターゲットが存在しないなどのエラーを返します。Build、Rebuild、Clean のどのターゲットを指定しても問題ありません。いずれの場合も機能しません。

ソリューションのプロジェクト固有のターゲットを指定するという目標を達成するにはどうすればよいですか?

MSDN ドキュメントは機能しません。それとも私は何かを逃しましたか?

4

2 に答える 2

40

注: この回避策は Microsoft によって公式にサポートされていないため、永久に機能するという保証はありません。


簡潔な答え

SLN ファイルのあるフォルダーに、次の内容のファイルを作成しますbefore.{YourSolution}.sln.targets(中括弧内を必要なものに置き換えます)。

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="{MyCompany_MyProduct_WebApp:WebPublish}">
    <MSBuild
        Condition="'%(ProjectReference.Identity)' == '{$(SolutionDir)MyCompany.MyProduct.WebApp\MyCompany.MyProduct.WebApp.csproj}'"
        Projects="@(ProjectReference)"
        Targets="{WebPublish}"
        BuildInParallel="True"
        ToolsVersion="4.0"
        Properties="BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)"
        SkipNonexistentProjects="%(ProjectReference.SkipNonexistentProjects)" />
  </Target>
</Project>

その後、コマンドラインを実行できます:

msbuild {YourSolution}.sln /t:{MyCompany_MyProduct_WebApp:WebPublish}

長い答え

環境変数 を追加MSBUILDEMITSOLUTIONしてその値を 1 に設定すると、MSBuild はソリューションとプロジェクト用に生成された一時ファイルを削除しません。

これにより、ソリューション フォルダーで生成されたファイルを検索{YourSolution}.sln.metaprojして生成することができ{YourSolution}.sln.metaproj.tmpます。これらは標準の MSBuild プロジェクト ファイルです。

MSBuild 3.5の場合、生成されたファイルは{YourSolution}.sln.cache環境変数に関係なく保持されます。これらのファイルを分析すると、プロセスの低レベルの詳細を理解し、利用可能なカスタマイズの機会を確認できます。

.Metaproj ファイルでプロジェクト固有のターゲットを指定して MSBuild を実行すると、プロジェクト固有のターゲットのリストがハードコードされており、標準のターゲットのみがサポートされていることがわかります(ビルド、リビルド、クリーン、コンパイル、パブリッシュ。注: パブリッシュと WebPublish)。は同じではありません)。MSBuild 3.5は、Clean、Rebuild、および Publish ターゲットと、"Build" を意味するプロジェクト名だけのターゲットのみを生成します。

また、自動生成されたターゲットの名前にすぎないNotInSlnfolder:Rebuildこともわかります。実際には、MSBuild はそれを解析せず、プロジェクトの名前と場所を気にしません。また、自動生成されたターゲット名は、プロジェクト名がソリューション フォルダー階層内にある場合は、プロジェクト名を指定することに注意してください。SolFolder\SolSubfolder\ProjectName:Publish

もう 1 つ重要なことがわかります。MSBuild ターゲット名はドットをサポートしていませんプロジェクト名のすべてのドットはアンダースコアに置き換えられます。たとえば、という名前のプロジェクトのMyCompany.MyProduct.Components場合、コマンド ラインで次のように指定する必要があります。

/t:MyCompany_MyProduct_Components:Rebuild

そのため、標準のプロジェクト固有のターゲット Build でさえ機能しませんでした。私のプロジェクト名にはドットが含まれていました。

file を分析する{YourSolution}.sln.metaproj.tmpと、実行時にbefore.{YourSolution}.sln.targetsおよびという名前のファイルからターゲットをインポートしようとすることがわかります (after.{YourSolution}.sln.targetsそれらのファイルが存在する場合)。これには、この MSBuild の制限/バグを回避するための鍵があります。

于 2012-08-22T21:51:01.183 に答える
1

ソリューション ファイルをテキスト エディターで開き、次の行が存在するかどうかを確認し、存在しない場合は追加できます。

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /><Project>タグの内側。

これがお役に立てば幸いです。

于 2016-07-15T12:45:17.680 に答える