代码重用,用于Visual Studio vcxproj文件中的文件存在测试

时间:2016-12-02 16:55:45

标签: visual-studio msbuild

我有一个vcxproj文件,其中包含NMakeBuildCommandLine部分中的显式Windows shell命令:

<NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
move file1 file2
</NMakeBuildCommandLine>

我正在使用MSBuild直接或通过sln文件执行vcxproj。问题是当file1不存在时,输出非常无用,甚至不会列出文件的名称:

The system cannot find the file specified.

我天真的解决方案是将move file1 file2替换为:

if exist file1 (move file1 file2) else (echo file1 does not exist &amp;&amp; exit 1)

(请注意,我需要写&amp;&amp;而不是&&。)

这很有效,但它容易出错,因为我需要每行键入file1三次,并确保它们都匹配。 file1只是需要移动的众多文件中的一个。此外,一系列命令在各种构建配置中几乎相同。

如何避免在命令行和构建配置中重复自己?我认为UserMacros属性组可能对我有帮助,但我无法弄清楚如何通过IDE编写这样的宏。 (在Visual Studio中右键单击项目不会显示用于输入用户宏的字段。)我也无法在Internet上找到有关此部分语法的任何讨论,因此我不知道如何使用文本编辑器(我实际上更喜欢)。

在vcxproj文件中可能还有一种更好的方法来识别需要存在的文件,因此我对任何替代方案持开放态度。

1 个答案:

答案 0 :(得分:1)

MsBuild像大多数其他编程语言properties一样拥有'变量'。您在项目文件xml中的PropertyGroup元素中声明一个,然后使用$(PropertyName)语法重用它。案例:

<PropertyGroup>
  <Src>/path/to/my/src</Src>
  <Dst>/path/to/my/dst</Dst>
</PropertyGroup>

<NMakeBuildCommandLine>
if exist $(Src) (move $(Src) $(Dst)) else (echo $(Src) does not exist &amp;&amp; exit 1)
</NMakeBuildCommandLine>

如果你想使用IDE,如果你有很多值可能会很乏味,你确实可以使用所谓的UserMacros,但你必须在一个专利表中声明它们。转到View-&gt; Property Manager,右键单击您的项目并选择“添加新属性表”。双击它,转到“用户宏”并在那里添加键/值对。如果您保存所有内容并查看生成的文件,您将看到vcxproj现在导入属性表,而propertiesysheet本身有一个PropertyGroup,如上所示 - 但可以通过IDE进行编辑。

作为一种可能更好(更少重复,更容易自动化)的替代方案,从长远来看,您可以使用MsBuild代码来检查文件存在和移动文件,这样您只需要编写一次移动命令就可以了MsBuild loop超过items。这些是在ItemGroup中声明的。在这里解释一切有点超出范围,但一个例子应该清楚地说明:

<Target Name="BatchMove">
  <ItemGroup>
    <SrcFiles Include="file1">
      <Dest>file2</Dest>
    </SrcFiles>
    <SrcFiles Include="file3">
      <Dest>file4</Dest>
    </SrcFiles>
  </ItemGroup>
  <Warning Text="Source file %(SrcFiles.Identity) does not exist" Condition="!Exists(%(SrcFiles.Identity))" />
  <Move SourceFiles="%(SrcFiles.Identity)" DestinationFiles="%(SrcFiles.Dest)" Condition="Exists(%(SrcFiles.Identity))" />
</Target>

这声明了2个源文件file1 / file3及其各自的目标文件file2 / file4。如果源不存在(使用标准的MsBuild Exists检查),则会显示一条消息,否则会将其移动到目标位置。那些%字符将使它们在SrcFiles集合的每个元素上循环出现。要添加更多文件,只需添加到ItemGroup即可。最后一步是从nmake命令行调用此目标,这只需通过调用文件本身的msbuild并告诉它运行目标来完成:

<NMakeBuildCommandLine>
msbuild $(MSBuildThisFile) /t:BatchMove
</NMakeBuildCommandLine>