代码之家  ›  专栏  ›  技术社区  ›  bwerks

是否在使用msbuild projectreference的生成中包含其他文件?

  •  2
  • bwerks  · 技术社区  · 6 年前

    我有一个类库,它依赖于几个文件,并且这些文件必须打包以便与依赖于此库的任何项目一起部署。现在,这意味着除了将库添加为msbuild prjectreference之外,还必须自定义这些依赖项目中的每一个,以确保它们复制文件。添加更多文件时,必须更新所有项目。

    我一直在浏览microsoft.common.targets,寻找一种将这些文件与库自己的项目文件的输出包含在一起的方法,因此任何对库具有项目引用的项目在进行生成时都将自动获取这些文件。我还没有得到任何工作,但我更普遍地好奇,如果这是可能的。它看起来应该是这样的,并且CopyFileMarkedCopyLocal目标甚至考虑到一个原本不使用的(destinationSubdirectory)元数据项,该项允许自定义放置这些文件,这将是完美的。

    我认为我缺少的是,对于构建依赖于项目B的项目A来说,将项目B的项目输出添加到项目A的构建项中的部分。

    编辑 :leo的评论,我没有注意到用copytooputdirectory标记的文件也被复制到依赖的项目输出目录,因为我们使用的项组的名称不是content、embeddedresource、none等。更深入地挖掘,使用这些项的目标是getcopytooputdirectoryitemsd它似乎递归地调用msbuild任务来确定项目输出,因此我应该能够定义一些自定义目标,这些目标可以导入到我们的项目中,从而在getcopyToOutputDirectoryItems目标中添加自定义项组,这样我们就不必使用content/none等。

    但是,进行复制的目标是CopyOutOfDateSourceItemsOutputDirectoryWays,这并不尊重%(DestinationSubdirectory),因此所有这些文件都直接复制到$(OutDir)。

    我的新目标是查看是否有某种方法可以将自定义文件添加到依赖项目的referencecopyLocalPaths项组中,以便由CopyFileMarkedCopyLocal目标(确实使用了%(destinationSubdirectory)复制这些文件。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Leo Liu    6 年前

    为CopyOutOfDateSourceItemsOutputDirectoryWays目标中的项组添加自定义生成操作

    上面的标题应该更接近bwerks的目标。作为测试,我们可以知道itemgroups的自定义生成操作不会复制到输出目录,因此我们需要将自定义生成操作复制到目标目录。 _CopyOutOfDateSourceItemsToOutputDirectoryAlways

    要完成此操作,请打开文件 Microsoft.Common.CurrentVersion.targets 在msbuild 15.0文件夹中 C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets (确保您有足够的权限并进行备份),找到目标 _复制输出数据源项输出目录路径 :

    <Copy
        SourceFiles = "@(_SourceItemsToCopyToOutputDirectoryAlways)"
        DestinationFiles = "@(_SourceItemsToCopyToOutputDirectoryAlways->'$(OutDir)%(TargetPath)')"
        ...
            >
    
      <Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
    
    </Copy>
    

    然后我们可以知道复制源文件是 @(_SourceItemsToCopyToOutputDirectoryAlways) ,搜索 _SourceItemsToCopyToOutputDirectoryAlways 在目标中,你会发现:

    <ItemGroup>
      <_SourceItemsToCopyToOutputDirectoryAlways KeepMetadata="$(_GCTODIKeepMetadata)" Include="@(ContentWithTargetPath->'%(FullPath)')" Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
      <_SourceItemsToCopyToOutputDirectory       KeepMetadata="$(_GCTODIKeepMetadata)" Include="@(ContentWithTargetPath->'%(FullPath)')" Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
    </ItemGroup>
    

    可以知道源文件是 @(ContentWithTargetPath) ,继续搜索 ContentWithTargetPath 在目标中,我们得到了以下信息:

    <AssignTargetPath Files="@(Content)" RootFolder="$(MSBuildProjectDirectory)">
      <Output TaskParameter="AssignedFiles" ItemName="ContentWithTargetPath" />
    </AssignTargetPath>
    

    因此,我们可以知道目标是如何将默认的构建操作文件复制到输出目录。

    现在 ,转到自定义生成操作,我们只需要将自定义生成操作添加到 ItemName="ContentWithTargetPath" ,因此在文件中添加以下内容 Microsoft.Common.CurrentVersion.Targets :

    <AssignTargetPath Files="@(MyBuildAction)" RootFolder="$(MSBuildProjectDirectory)">
      <Output TaskParameter="AssignedFiles" ItemName="ContentWithTargetPath" />
    </AssignTargetPath>
    

    保存它。

    对于项目文件中的文件 .csproj :

      <ItemGroup>
        <MyBuildAction Include="TextFile1.txt">
          <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </MyBuildAction>
      </ItemGroup>
    

    enter image description here

    希望这有帮助。