.NET Core 2.1:如何在Visual Studio 2017中进行调试期间触发在项目文件中定义的复制任务?

Hak*_*MK1 1 msbuild .net-core

有些文件位于其他目录中,我想在构建和发布之前自动将其复制到项目文件夹中。

经过一些研究和实验,我得出了以下.csproj文件。

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <RuntimeFrameworkVersion>2.1.4</RuntimeFrameworkVersion>
    <TieredCompilation>true</TieredCompilation>
    <PreserveCompilationContext>true</PreserveCompilationContext>
  </PropertyGroup>

  <ItemGroup>
    <APIDefinition Include="D:\SomePlace\*.API.*.yaml" />
  </ItemGroup>

  <Target Name="CopyFiles" BeforeTargets="Compile;Build;Publish">
    <Copy SourceFiles="@(APIDefinition)" DestinationFolder="wwwroot" />
    <Copy SourceFiles="D:\SomePlaceElse\BaseAPISettings.json" DestinationFolder="$(MSBuildProjectDirectory)" />
  </Target>

  <ItemGroup>
    <Compile Remove="wwwroot\**\*;node_modules;bower_components" />
    <None Update="**.user;**.vspscc">
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.4" />
  </ItemGroup>

</Project>
Run Code Online (Sandbox Code Playgroud)

在这里,我定义了CopyFiles目标,该目标应该在放置目标之前运行。该目标使用复制任务将YAML格式的API定义文件和基本API设置复制到项目目录。

这在构建,发布等过程中效果很好。此外,如果我在IDE中删除本地文件,它会立即从源文件中重新复制它。

有时,我会在调试会话之间对这些文件进行更改。然后,当我从Visual Studio开始调试时,由于项目文件没有更改,因此显然已运行的项目正在运行。

由于未构建项目,因此不会触发我的复制任务,并且最终在调试过程中出现陈旧文件。

当我在IDE中执行“开始调试F5”时,无论项目构建状态如何,都可以做些什么来触发我的复制任务?

PS:我正在使用Visual Studio 2017 15.8.5,并以.NET Core 2.1.4运行时为目标(如果有任何区别)。

Mar*_*ich 5

为了完全集成到Visual Studio中项目系统的最新检查中,我建议进行以下更改:

  1. 事先知道项目的源路径和目标路径
  2. 将它们注册到最新的检查系统。(还需要黑客以确保重新编译项目源代码,以便输出具有新的时间戳记)
  3. 使MSBuild目标本身递增。当不必复制文件时,这也有助于命令行构建。

完整的更改如下所示:

<ItemGroup>
  <CustomCopyFile Include="..\TestFiles\*.API.*.yaml"
                  TargetPath="wwwroot\%(Filename)%(Extension)" />
  <CustomCopyFile Include="..\TestFiles\BaseAPISettings.json"
                  TargetPath="%(Filename)%(Extension)" />
  <UpToDateCheckInput Include="@(CustomCopyFile)" />
  <UpToDateCheckBuild Include="@(CustomCopyFile->'%(TargetPath)')"
                      Original="@(CustomCopyFile)" />
  <CustomAdditionalCompileInputs Include="@(CustomCopyFile->'%(TargetPath)')" />
</ItemGroup>

<Target Name="CopyFiles" 
        BeforeTargets="BeforeBuild;BeforePublish"
        Inputs="@(CustomCopyFile)" 
        Outputs="@(CustomCopyFile->'%(TargetPath)')">
  <Copy SourceFiles="@(CustomCopyFile)"
        DestinationFiles="@(CustomCopyFile->'%(TargetPath)')" />
</Target>
Run Code Online (Sandbox Code Playgroud)

CustomCopyFile现在收集所有源文件,然后将期望的目标文件名放入TargetPath元数据中。

UpToDateCheckInput 这些项之一告诉Visual Studio重新构建项目,如果其中一项发生更改。

UpToDateCheckBuild项目指示Visual Studio仅对照特殊源项目检查这些项目。这对于此示例项目是多余的,但如果目标路径不在项目目录中,而是在某些中间输出(obj ..)文件夹中,并且没有重新评估将看到这些新文件,则可能会有所帮助。如果在处理过程中还修改了文件(例如替换文件中的变量),这也将很有帮助。

CustomAdditionalCompileInputs之所以会出现这种情况,是因为将项目复制到项目文件夹中,并自动将其视为“输入到输出”。因此,如果源文件发生更改,我们将强制重新编译项目。如果我们不这样做,则在更改源yaml文件后,它将永远不会考虑该项目是最新的,因为它们比已编译的app.dll文件要新。