我正在使用以下PostBuildEvent
<PostBuildEvent>
IF DEFINED $(MyEnvVar) (
mkdir "C:\tmp\"
copy "$(TargetPath)" "$(MyEnvVar)/Addins/Software/bin/$(PlatformName)/$(TargetFileName)"
)
</PostBuildEvent>
如果定义了我的MyEnvVar
,则此事件有效。但是,如果未定义变量,则会收到错误 MSB3073 (代码为255)。
如果变量存在,我如何定义PostBuild任务以执行一些cmd操作(创建文件夹复制文件,如上所示),否则,什么也不做?
答案 0 :(得分:2)
您绝对不应该真正使用构建后事件。 只需创建一个目标,然后使其在构建目标之后运行即可。 在该目标中,让它复制所需的文件。像这样:
<Target Name="CopyMyStuff" AfterTargets="Build" Condition="exists('$(MyEnvVar)')" >
<Copy SourceFiles="$(TargetPath)" DestinationFolder="$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\" SkipUnchangedFiles="true" />
</Target>
我认为如果目录不存在,此复制任务将创建该目录。不错的奖励。
答案 1 :(得分:2)
在用$(Variable)
文本创建批处理文件以在编译后临时执行之前,Visual Studio用XML元素PostBuildEvent
的值中的Visual Studio变量的字符串替换所有出现的PostBuildEvent
并成功完成链接过程。
如果根本不存在像MyEnvVar
这样的引用的Visual Studio变量,则将其引用$(Variable)
替换为空字符串。这将在命令行中显示:
IF DEFINED (
在此 IF 条件下,执行批处理文件的Windows命令处理器期望DEFINED
之后的环境变量的名称,而不是左括号。这是cmd.exe
在评估命令 IF 的参数时检测到的语法错误,导致退出了批处理文件的处理。
一种解决方案正在使用:
<PostBuildEvent>
set "MyEnvVar=$(MyEnvVar)"
if defined MyEnvVar (
mkdir "C:\tmp\"
copy "$(TargetPath)" "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\$(TargetFileName)"
)
</PostBuildEvent>
第一行将Visual Studio变量MyEnvVar
的当前字符串值分配给环境变量MyEnvVar
。因此,环境变量MyEnvVar
是因为set "MyEnvVar=string value"
而用字符串定义的,或者在Visual Studio变量MyEnvVar
不存在或为空的情况下,在第一行之后肯定没有定义(不再)字符串,导致执行set "MyEnvVar="
。
命令 IF 始终具有有效的语法,因为现在始终在此命令行上指定要检查定义的环境变量的名称,而与Visual Studio变量{{1 }}。
其他说明:Windows上的目录分隔符是MyEnvVar
,而不是目标路径中使用的\
。 Windows文件系统访问内核功能会自动将标准合格文件名中的所有/
替换为/
,作为自动文件路径更正的一部分。但是最好使用100%正确的语法编写构建后事件代码,而不依赖于文件路径上的自动错误更正。
答案 2 :(得分:1)
我复制了您的脚本并遇到了相同的问题。根据错误消息The syntax of the command is incorrect
,语法有问题,可能是空格,换行符,我不确定:(
如何定义PostBuild任务来执行一些cmd操作,(创建 文件夹复制文件(如上所示),如果变量存在,或执行 如果没有,什么都没有?
一种解决方法::也许您可以从PostBuildEvent内部删除Judgment语句。然后使用msbuild condition来判断变量是否已定义,请尝试使用如下脚本:
<!--<PropertyGroup>
<MyEnvVar>C:\Test</MyEnvVar>
</PropertyGroup>-->
<PropertyGroup>
<PostBuildEvent Condition="$(MyEnvVar)!=''">
IF NOT EXIST "C:\tmp\" mkdir "C:\tmp\"
IF NOT EXIST "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\" mkdir "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\"
copy "$(TargetPath)" "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\"
</PostBuildEvent>
</PropertyGroup>
在vs中,右键单击项目并将脚本添加到其中,位置应为:
<Project...>
...
<!--<PropertyGroup>
<MyEnvVar>C:\Test</MyEnvVar>
</PropertyGroup>-->
<PropertyGroup>
<PostBuildEvent Condition="$(MyEnvVar)!=''">
IF NOT EXIST "C:\tmp\" mkdir "C:\tmp\"
IF NOT EXIST "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\" mkdir "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\"
copy "$(TargetPath)" "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\"
</PostBuildEvent>
</PropertyGroup>
</Project>
然后right-click the project
并选择reload project
并检查它是否有助于实现您的原始目标。
1。PostBuildEvent
仅在定义MyEnvVar
并具有其值时才起作用。
2。当C:\tmp\
和$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\
目录不存在时,将调用两个mkdir命令
3。然后,复制命令会将项目的输出复制到目标文件夹,我删除了$(TargetFileName)
,因为它代表xxx.exe或xxx.dll,我认为这不是必需的,或者也许是您真正想要的是$(AssemblyName)
。请让我知道它是否有助于解决您的问题:)