c# - Visual Studio 如何确定它是否必须启动 MSBuild?

标签 c# visual-studio msbuild

我过去为我的 C++ 项目做了很多 MSBuild 自定义。 MSBuild 目标的 InputOutput 属性用于确定是否必须执行目标。此外,Visual Studio 使用 .tlog 文件(位于中间目录中)来确定是否必须调用 MSBuild。

现在我正在处理一个 C# 项目。我写了一个简单的 MSBuild 目标,它将一个文件复制到输出目录:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="CopyMyFile" BeforeTargets="AfterBuild" Inputs="$(ProjectDir)File.dat" Outputs="$(TargetDir)FileRenamed.dat">
    <Copy SourceFiles="$(ProjectDir)File.dat" DestinationFiles="$(TargetDir)FileRenamed.dat" OverwriteReadOnlyFiles="true">
    </Copy>
  </Target>
</Project>

如果通过 MSBuild.exe 调用生成,目标将按预期工作。如果目标文件不存在或源文件已被修改,则复制文件。

如果我在 Visual Studio 中调用构建,它不会按预期工作。如果我从输出目录中删除文件,Visual Studio 不会调用 MSBuild。另一方面,每次我在修改源文件后构建项目时都会调用 MSBuild,即使没有进行其他更改也是如此。

似乎 Visual Studio 只是将项目中的每个文件与输出文件(.exe、.dll 或 .pdb)进行比较。如果项目中的任何文件比输出文件新,将调用 MSBuild。在我的例子中,MSBuild 不会更新 .exe 文件,因此会一次又一次地调用 MSBuild。

在 C++ 项目中,此行为由 .t​​log 文件控制。 C# 项目中有类似的东西吗?

非常感谢!

最佳答案

答案可能是不,与tlog机制没有任何相似之处。不过我不是 100% 确定,也因为很奇怪你不能做一些非常基本的事情,因为这意味着 MS 基本上放弃了 C#(和类似)项目的跟踪器东西,但没有用可以 Hook 的东西代替它由用户。

使用 procmon 你可以看到 VS 获取输出和输入文件的时间戳,但我在任何地方都找不到干扰它视为输入和输出文件的方法。看起来 VS 获得了项目文件中直接包含的所有内容的列表(即引用/内容/编译/.. VS 中显示的项目组),而不是 Taget 的输入/输出中列出的内容,并且在构建只比较那些项目的时间戳。如果所有内容(好吧,就 VS 而言,所有内容)都是最新的,则不会为构建启动任何 msbuild 进程。

有一个解决方法,但不是很好:如果您添加一个“虚拟”内容项(例如右键单击项目->添加新项->文本文件)并将其设置为始终被复制(右键单击文本刚刚添加的文件 -> 属性 -> 复制到输出目录 -> 始终复制)然后 VS 将始终 开始构建,因此检查目标的输入与输出,如果你删除了 FileRenamed.dat,则运行。

关于c# - Visual Studio 如何确定它是否必须启动 MSBuild?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43185713/

相关文章:

msbuild - 如果目标失败,则停止 msbuild 进程

c# - 从两个不同的位置安装 ClickOnce 应用程序

c# - 使用 CSVHelper 映射 IEnumerable 属性

c# - 在 IDS4 和 ASP.NET Core 2.2 下使用 Jwt token 获取 401 访问安全页面

c# - 分两步将复选框值从 View 发送到 Controller ?

c# - 如何使安装程序的版本号与已安装程序集的版本号保持同步?

c# - 在代码隐藏中设置SqlDataSource的插入参数值

.net - 在.NET中调试调用的功能

c# - 如何在一个解决方案中的源项目之间共享多个二进制文件?

msbuild - 我可以从 Visual Studio Code 命令面板运行 MSBuild 脚本吗?