最終的に、プロジェクト Bを変更せずに自動的にコピーを実行することができました。IIya は解決にはほど遠いのですが、MyCustomTask でプロジェクト Aから生成するファイルのリストが動的であるため、静的に生成することはできないのが実情です。をさらに掘り下げた後Microsoft.Common.targets
、 ProjectB はtarget を呼び出すことによってプロジェクト AGetCopyToOutputDirectoryItems
からの出力のリストを取得することがわかりました。このターゲットは、AssignTargetPaths
それ自体がターゲット リスト プロパティに依存している依存先AssignTargetPathsDependsOn
です。
したがって、コンテンツを動的に生成し、このコンテンツを標準のプロジェクトの依存関係を通じて自動的にコピーするには、プロジェクト Aを 2 つの異なる場所でフックする必要があります。
- GetCopyToOutputDirectoryItemsを介してプロジェクト A のプロジェクト B
AssignTargetPathsDependsOn
によって間接的に呼び出されるためです。また、呼び出されたときにプロジェクト Aによって間接的に呼び出されます。ここでは、( Project Aによって) 生成されるか、 Project Bによって消費されるファイルのリストを出力しています。AssignTargetPathsDependsOn は、ファイルのリストの出力のみを担当するカスタム タスクを呼び出します (ただし、ファイルのリストは生成しません)。このファイルのリストは、.PrepareResource
MyCustomTaskList
CopyOutputDirectory
- プロジェクト Aで実際に
BuildDependsOn
コンテンツを生成するため。これは、コンテンツを生成する呼び出しを行います。MyCustomTask
これはすべて、ProjectA で次のようにセットアップされました。
<!-- In Project A -->
<!-- Task to generate the files -->
<UsingTask TaskName="MyCustomTask" AssemblyFile="$(PathToMyCustomTaskAssembly)"/>
<!-- Task to output the list of generated of files - It doesn't generate the file -->
<UsingTask TaskName="MyCustomTaskList" AssemblyFile="$(PathToMyCustomTaskAssembly)"/>
<!-- 1st PART : When Project A is built, It will generate effectively the files -->
<PropertyGroup>
<BuildDependsOn>
MyCustomTaskTarget;
$(BuildDependsOn);
</BuildDependsOn>
</PropertyGroup>
<Target Name="MyCustomTaskTarget">
<!-- Call MyCustomTask generate the files files that will be generated by MyCustomTask -->
<MyCustomTask
ProjectDirectory="$(ProjectDir)"
IntermediateDirectory="$(IntermediateOutputPath)"
Files="@(MyCustomFiles)"
RootNamespace="$(RootNamespace)"
>
</MyCustomTask>
</Target>
<!-- 2nd PART : When Project B is built, It will call GetCopyToOutputDirectoryItems on ProjectA so we need to generate this list when it is called -->
<!-- For this we need to override AssignTargetPathsDependsOn in order to generate the list of files -->
<!-- as GetCopyToOutputDirectoryItems ultimately depends on AssignTargetPathsDependsOn -->
<!-- Content need to be generated before AssignTargets, because AssignTargets will prepare all files to be copied later by GetCopyToOutputDirectoryItems -->
<!-- This part is also called from ProjectA when target 'PrepareResources' is called -->
<PropertyGroup>
<AssignTargetPathsDependsOn>
$(AssignTargetPathsDependsOn);
MyCustomTaskListTarget;
</AssignTargetPathsDependsOn>
</PropertyGroup>
<Target Name="MyCustomTaskListTarget">
<!-- Call MyCustomTaskList generating the list of files that will be generated by MyCustomTask -->
<MyCustomTaskList
ProjectDirectory="$(ProjectDir)"
IntermediateDirectory="$(IntermediateOutputPath)"
Files="@(MyCustomFiles)"
RootNamespace="$(RootNamespace)"
>
<Output TaskParameter="ContentFiles" ItemName="MyCustomContent"/>
</MyCustomTaskList>
<ItemGroup>
<!--Generate the lsit of content generated by MyCustomTask -->
<Content Include="@(MyCustomContent)" KeepMetadata="Link;CopyToOutputDirectory"/>
</ItemGroup>
</Target>
このメソッドは、Common.Targets を使用しているあらゆる種類の C# プロジェクトで機能します (したがって、純粋なデスクトップ、WinRT XAML アプリ、または Windows Phone 8 プロジェクトで機能します)。