我有一个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 && exit 1)
(请注意,我需要写&&
而不是&&
。)
这很有效,但它容易出错,因为我需要每行键入file1
三次,并确保它们都匹配。 file1
只是需要移动的众多文件中的一个。此外,一系列命令在各种构建配置中几乎相同。
如何避免在命令行和构建配置中重复自己?我认为UserMacros
属性组可能对我有帮助,但我无法弄清楚如何通过IDE编写这样的宏。 (在Visual Studio中右键单击项目不会显示用于输入用户宏的字段。)我也无法在Internet上找到有关此部分语法的任何讨论,因此我不知道如何使用文本编辑器(我实际上更喜欢)。
在vcxproj文件中可能还有一种更好的方法来识别需要存在的文件,因此我对任何替代方案持开放态度。
答案 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 && 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>