【问题标题】:How to create a msbuild target to run after "Run" target (dotnet run)?如何创建一个 msbuild 目标以在“运行”目标(dotnet 运行)之后运行?
【发布时间】:2021-09-30 05:43:05
【问题描述】:

我正在尝试创建一个 msbuild csproj,我可以在其中调用 dotnet run myproject 并在执行后删除 bin/obj 文件夹。 但是,CustomAfterRun 目标(如下)不会在 Run 目标之后执行。

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
    <EnableDefaultItems>false</EnableDefaultItems>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="Program.cs" />
  </ItemGroup>

  <Target Name="CustomAfterRun" AfterTargets="Run">
    <Message Importance="high" Text="[msbuild] Cleaning bin and obj..."/>
    <RemoveDir Directories="$(TargetDir)" />
    <RemoveDir Directories="$(ProjectDir)$(BaseIntermediateOutputPath)" />
  </Target>
</Project>

如果我创建一个目标CustomAfterBuild(使用AfterTargets="Build"),它可以正常工作(当我运行dotnet build myproj 时它会在构建后执行)。

这是一个错误还是我做错了什么?

还有最疯狂的部分:如果在CustomAfterBuild 内部调用&lt;CallTarget Targets="Run" /&gt;,那么在构建之后调用我的程序,在这种情况下CustomAfterRun 运行良好!这种方法的缺点是程序输出只有在我启用详细的详细级别时才可见,并且在 CustomAfterRun 运行(删除 bin/obj 文件夹)之后,它也会尝试再次运行程序(意味着运行目标是两次调用?!)给我一个错误:System.ComponentModel.Win32Exception (2): The system cannot find the file specified.

编辑:作为替代方案,我也尝试覆盖 Run 目标,但这根本不起作用:

<Project>
  <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
    <EnableDefaultItems>false</EnableDefaultItems>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="Program.cs" />
  </ItemGroup>

  <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />

  <Target Name="Run" >
    <Message Importance="high" Text="[msbuild] overriden..."/>
  </Target>
</Project>

【问题讨论】:

    标签: msbuild msbuild-task


    【解决方案1】:

    原来我对dotnet run 有一个错误的假设。

    • dotnet msbuild 基本上是调用msbuild 的外观。 dotnet build 只是dotnet msbuild -restore 的快捷方式,因此它将恢复 nuget 包并构建(默认目标)。 dotnet clean 也调用 msbuild(干净的目标)。

    • 在类似的意义上我期待 dotnet run 使用来自 msbuild 的 Run 目标,但它没有。它调用dotnet msbuild(如果需要),但它会使用 msbuild 运行输出 WITHOUT
      如果我运行msbuild -target:Run,运行后的事件就可以正常工作!

    因此,一种可能的解决方案是使用普通的 msbuild。
    例如:dotnet msbuild /t:Restore;Build;Run;Clean MyProj.csproj),

    但是,另一个让我烦恼的行为是,当通过 msbuild 启动程序时,我在控制台输出中看不到颜色(如果有的话)。这可能是因为 msbuild 使用控制台重定向来运行我的程序。 dotnet run 幸好没有这种行为,所以我的最终解决方案是:

    dotnet run &amp; dotnet clean

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net5.0</TargetFramework>
        <EnableDefaultItems>false</EnableDefaultItems>
      </PropertyGroup>
      <ItemGroup>
        <Compile Include="Program.cs" />
      </ItemGroup>
    
      <!-- Clean is not so perfect, clear leftovers -->
      <Target Name="CleanBinObj" AfterTargets="Clean">
        <RemoveDir Directories="$(ProjectDir)$(BaseOutputPath)" />
        <RemoveDir Directories="$(ProjectDir)$(BaseIntermediateOutputPath)" />
      </Target>
    
      <!-- If someone uses msbuild to launch, force a clean.. -->
      <Target Name="CustomAfterRun" AfterTargets="Run">
        <CallTarget Targets="Clean" />
      </Target>
    </Project>
    

    或者对于我的特定情况,我将在同一个文件夹中保留多个单独的 cs 程序(每个都有自己的 csproj),并且我想用我的文件的单独(临时)文件夹覆盖 bin/obj 文件夹:

    <Project>
    
      <PropertyGroup>
        <TempDir>$(MSBuildProjectName).cs.tmp\</TempDir>
        <BaseOutputPath>$(TempDir)</BaseOutputPath>
        <BaseIntermediateOutputPath>$(TempDir)</BaseIntermediateOutputPath>
      </PropertyGroup>
    
      <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
    
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net5.0</TargetFramework>
        <EnableDefaultItems>false</EnableDefaultItems>
      </PropertyGroup>
    
      <ItemGroup>
        <Compile Include="$(MSBuildProjectName).cs" />
      </ItemGroup>
    
      <!-- Clean is not so perfect, clear leftovers -->
      <Target Name="CleanBinObj" AfterTargets="Clean">
        <Message Importance="high" Text="Cleaning $(TempDir) (bin/obj)..."/>
        <RemoveDir Directories="$(TempDir)" />
      </Target>
    
      <!-- If someone uses msbuild to launch, force a clean.. -->
      <Target Name="CustomAfterRun" AfterTargets="Run">
        <CallTarget Targets="Clean" />
      </Target>
      
      <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
    
    </Project>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-08
      • 2010-12-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多