MSBuild目标BeforeCompile,在加载项目文件时触发

xad*_*eka 2 msbuild msbuild-task visual-studio-2010 visual-studio

这是一个与我的整体问题有关的较小问题。这就是我想要完成的。

我创建了一个修改我的源文件的任务。每当我编译和构建时,我都希望使用修改后的cs文件进行编译。香港专业教育学院试图做一个控制台应用程序,我从prebuild事件调用,但我发现只有一些修改的文件被编译。即使我没有在编辑器中打开它们。然后,我尝试在csproj文件中使用与以下xml一起使用的自定义任务:

<Target Name="BeforeCompile">
    <MyCustomTask />
</Target>
Run Code Online (Sandbox Code Playgroud)

而且我还用它来获得相同的结果:

<PropertyGroup>
    <CompileDependsOn>
        $(CompileDependsOn);
        MyCustomTarget;
    </CompileDependsOn>
</PropertyGroup>
<Target Name="MyCustomTarget">
    <MyCustomTask />
</Target>
Run Code Online (Sandbox Code Playgroud)

这样就可以完成我想做的事情,但是我发现,每当加载项目文件时,它都会触发我的目标。我认为这只会在编译我的代码时运行。因此很明显,它是在编译或加载项目文件时触发与编译相关的目标的。

理想情况下,我希望仅在我明确构建项目时(即,手动构建或开始调试时)才触发该目标。我可以做些什么来实现这一目标?

jes*_*ing 5

从文档中,始终将这些目标作为加载Visual Studio的一部分来执行。这还将包括这些目标具有的任何依赖关系。

设计时目标执行

Visual Studio尝试在加载项目时尝试使用某些名称执行目标。这些目标包括CompileResolveAssemblyReferencesResolveCOMReferencesGetFrameworkPathsCopyRunEnvironmentFiles。Visual Studio运行这些目标,以便可以初始化编译器以提供IntelliSense,可以初始化调试器,并且可以解析解决方案资源管理器中显示的引用。如果不存在这些目标,则项目将正确加载和生成,但Visual Studio中的设计时体验将无法完全发挥作用。

资源

比较运行时msbuild /v:diag /t:compile与执行哪些目标时,msbuild /v:diag /t:build您会看到ResGen并跳过了其他一些目标。尝试to带其中之一可能会帮到您。

还请记住有关Visual Studio托管过程的这些内容及其对动态更改文件的影响:

Visual Studio编译器可能正在使用文件的缓存版本。这会引起问题,要么在文件obj夹下显式创建文件,然后将它们动态地包含在MsBuild中,那样Visual Studio就不会使用它在文件中的内存实例。通过从ItemGroup中删除源文件并添加自己的生成副本来执行此操作,则需要在自定义目标中执行以下操作:

<ItemGroup>
   <Compile Remove="ThefileYourWantGone.cs" />
   <Compile Include="$(BaseIntermediateOutputPath)\ThefileYourWantGone.g.cs/>
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)

除了对其进行硬编码,您还可以使用转换表达式:

<ItemGroup>
   <Compile Include="ThefileYourWantGone.cs">
      <IsRegenerated>true</IsRegenerated>
   </Compile>
</ItemGroup>

<ItemGroup>
   <RegeneratedCompile
        Include="@(Compile)"
        Condition="'%(Compile.IsRegenerated)' == 'true'"
   />
</ItemGroup>

<YourCustomtaskThatOutputs Inputs="@(RegeneratedCompile)" Outputs="@(RegeneratedCompile-> '$(BaseIntermediateOutputPath)\%(relativedir)%(filename).g.%(extension)')" />

<ItemGroup>
   <Compile Remove="@(RegeneratedCompile)" />
   <Compile Include="@(RegeneratedCompile-> '$(BaseIntermediateOutputPath)\%(relativedir)%(filename).g.%(extension)')" />
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)

备择方案

禁用主机编译器

或通过添加禁用HostCompiler

<UseHostCompilerIfAvailable>FALSE</UseHostCompilerIfAvailable>
Run Code Online (Sandbox Code Playgroud)

到第一个属性组(应该没有条件)以使Visual Studio始终使用磁盘版本(这会稍微减慢Visual Studio的生成速度)。

使您的任务对Visual Studio敏感

或者使您的构建任务了解,IVsMSBuildTaskFileManager并在更新文件时告诉它。您将需要在Visual Studio注册表中注册构建任务,以将其标记为“可以安全加载”