22

以下のファイルの出力先に別のフォルダを指定することはできますか?

<Content Include="test.stl">
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
4

4 に答える 4

44

/アイテムのLinkメタデータを使用して、別の出力フォルダーを指定できます。NoneContent

<Content Include="test.stl">
  <Link>some\folder\%(Filename)%(Extension)</Link>
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

include ステートメントでワイルドカードを使用する場合、これは、プロジェクト ディレクトリの外から来るファイルであっても、ディレクトリ階層を保持する方法でもあります。

<Content Include="..\shared\**\*">
  <Link>some\folder\%(RecursiveDir)%(Filename)%(Extension)</Link>
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

2.0.0 以降の SDK を使用する SDK ベースのプロジェクト (ASP.NET Core / .NET Core / .NET Standard プロジェクトの既定) では、LinkBaseメタデータを使用して同じことが実現できます。

<Content Include="..\shared\**\*" LinkBase="some\folder" CopyToOutputDirectory="PreserveNewest" />
于 2017-12-10T10:50:00.240 に答える
9

できますが、「コンテンツ」ではできません。アイテムのタスクにもよりますが、ハッキングできる組み込みのアイテムのほとんどは、問題や副作用に値するものではありません。

これに対処するための基本的な使い古されたパスがあります:)これは、.Netを実行している場合、厄介なPostBuild cmdシェルの方法も回避し、実際のビルドプロセスを使用します。

OPの質問の核心はここにあると思います。これはコア コンセプトであり、最短パスであり、副作用のない「出力パスへの相対」パス パラメーターを持つアイテム タイプを見つけることを保証します。

1) 後処理スタイル:

<ItemGroup>
  ...
  <MyTargets Include="test.stl"/>
  ...
</ItemGroup>

次に、一番下に(あなたがたどっているパスを使用して):

<PropertyGroup>
  <MyDeployDir>$(SolutionDir)$(Configuration)</MyDeployDir>
  <MyOtherDeployDir>$(SolutionDir)$(Configuration)\Templates</MyDeployDir>
</PropertGroup>

次に、既存のMS ビルドが含まれます (これを追加しないでください。マーカーとしてここにあります)。

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />

次に、「ビルド後」:

<Target Name="AfterBuild">
  <Copy SourceFiles="@(MyTargets)" DestinationFolder="$(MyDeployDir)" SkipUnchangedFiles="true" />
  <Copy SourceFiles="@(MyOtherTargets)" DestinationFolder="$(MyOtherDeployDir)" SkipUnchangedFiles="true" />
  <Copy SourceFiles="@(MyTargets2)" DestinationFolder="$(MyDeployDir)\IHeardYourMomLikesGrapeNuts" SkipUnchangedFiles="true" />
</Target>

根本的な問題は、プロジェクト アイテムはデフォルトでは何もしないということです。「コンテンツ」や「MyTarget」などのタイプがあります。何が起こるかを言うタイプです。必要なものを含むタスク、タイプ、またはビルド スクリプト インクルードを見つけることができるかもしれませんが、ビルド中にそのファイルで何が起こるかについては、itemgroup 内のアイテムに固有のものは何もありません。上記は、特別に構築された「タスク」のパワーのバランスですが、問題はありません。

追加したら

 <ItemGroup>
    <MyOutFiles Include="xxx.xxx" />

一度プロジェクト ファイルに追加すると、すべてのファイルの BuildAction リストに表示され、proj ファイルを手動で編集しなくても任意のファイルに設定できます。


2) ワンステップで

MSBuild のそれ以降のバージョンでは、'AfterBuild' ターゲット内に 'ItemGroup' を埋め込み、ファイルの残りの部分に触れることなく、上記を実行したり、他の手の込んだことを実行したりできます。これにより、たとえば、単純なインクルードを使用してビルドの結果を取得し、それを別の場所に置き換えることができます。これはすべて、RoboCopy を何も実行せず、より複雑なビルド ターゲット関数の処理に頼ることもありません。

<Target Name="AfterBuild">
  <ItemGroup>
    <MyOutFiles Include="$(OutDir)*.*" />
  </ItemGroup>
  <Copy SourceFiles="@(MyOutFiles)" DestinationFolder="$(SolutionDir)\Application" SkipUnchangedFiles="true" />

編集(反対票のため?、削除されてからの投稿者のコメント):

可能なメソッドを明確にし、繰り返しますが、このメソッドは MSBuild の「関数」や「RoboCopy」などの代替タスクを使用しませんが、「コンテンツ」などのアイテム タスクを作成する際に使用するようなコア機能を使用して、より純粋な MSBuild スタイルを示すことを意図していました。自体。

問題は、「次のファイルに別のフォルダー」を指定できるか、コンテンツ タグにこれを指定できるかということでした。MSBuild 関数を使用してすべての BuildAction を再ルーティングできますが、それが問題だとは思いません。

これは上記のように 1 ステップで実行できるので、これ以上複雑になることはないと思いますし、読みやすいと思います。以下は短い形式で、任意に処理できる独自の BuildAction を作成できます。いいえ、「コンテンツ」としてマークされた特定のファイルの別のフォルダーを選択するように「コンテンツ」に指示することはできませんが、かなり簡単に行う別のビルド アクションを作成できます。アクションを指示する StlFiles タグにメタ情報を挿入して、タグ自体に設定したり、コンテンツのようにプロセスの早い段階で StlFiles フックを設定したりすることもできますが、それはより複雑です。

<StlFiles Include="test.stl" />         
...
<Target Name="AfterBuild">
  <Copy SourceFiles="@(StlFiles)" DestinationFolder="$(SolutionDir)\Release\MyTypes" SkipUnchangedFiles="true" />
于 2012-09-01T22:52:33.357 に答える
1

この機能はコンテンツ アイテムには組み込まれていません。ただし、プロジェクト ファイルにターゲットを追加することで、それを追加できます。

あなたのプロジェクトでは、現在これを持っています:

<ItemGroup>
  <Content Include="test.stl">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </Content>
</ItemGroup>

特定の 1 つのファイルを別の場所にコピーする場合は、これを末尾 (「Project」タグの終了タグの前) に追加します。

<Target Name="CopyStl" AfterTargets="AfterBuild">
  <!-- One or the other of these Copy tasks should do what you want --> 
  <Copy Condition="'%(Identity)' == 'test.stl'" SourceFiles="@(Content)" SkipUnchangedFiles="true" DestinationFolder="$(OutputPath)\path\under\outputpath" />
  <Copy Condition="'%(Identity)' == 'test.stl'" SourceFiles="@(Content)" SkipUnchangedFiles="true" DestinationFolder="$(MSBuildProjectDirectory)\..\path\outside\project" />
</Target>

さらにいくつかのファイルを追加して同じフォルダーにコピーする場合は、代わりに次の方法を試してください。

<Target Name="CopySomeFiles" AfterTargets="AfterBuild">
  <!-- One or the other of these Copy tasks should do what you want --> 
  <Copy Condition="'%(Identity)' == 'test.stl' AND '%(Identity)' == 'test2.stl'" SourceFiles="@(Content)" SkipUnchangedFiles="true" DestinationFolder="$(OutputPath)\path\under\outputpath" />
  <Copy Condition="'%(Identity)' == 'test.stl' AND '%(Identity)' == 'test2.stl'" SourceFiles="@(Content)" SkipUnchangedFiles="true" DestinationFolder="$(MSBuildProjectDirectory)\..\path\outside\project" />
</Target
于 2012-09-05T05:22:45.090 に答える
0

出力フォルダーを追加で指定する方法はありませんが、ビルドの前後にファイルをコピーできます。

于 2012-09-01T23:07:56.750 に答える