在自定义生成命令中使用某些批处理变量名称时出现损坏

时间:2015-01-16 18:56:18

标签: visual-studio batch-file msbuild

我有一个带有自定义构建命令的VS2013项目。在命令脚本中,我设置了一个环境变量,并在同一个脚本中再次读出它。我可以通过调用set确认设置变量是否有效。但是,根据变量名称,我无法再读出来。

以批处理脚本形式运行时,以下工作正常:

set AVAR=xxx
set ABLAH=xxx
set BBLAH=xxx
set DEV=xxx
set @ABLAH=xxx

echo %AVAR%
echo %ABLAH%
echo %BBLAH%
echo %DEV%
echo %@ABLAH%

但是在项目中产生以下输出:

1>  xxx
1>  «LAH
1>  »LAH
1>  ÞV
1>  xxx

在这种情况下,名称AVAR有效,但其他许多人都没有。此外,以@开头的变量似乎也有效。知道发生了什么事吗?

2 个答案:

答案 0 :(得分:3)

我找到了解决方案。 Visual Studio (msbuild) converts %XX escape sequences like in URLs.我只是在URL中预期它,就像浏览器一样。但是,它似乎在任何地方都取而代之。

因此,遇到%ABCDE%时,它会识别%AB并插入字符« = 0xAB,并将«CDE%提供给批处理解释程序。但是如果代码不是有效的十六进制数字,它会默默地忽略它,并且解释器会看到正确的字符。这就是为什么开头@的变量名一直有用的原因。

所以解决办法是至少逃避前面有效十六进制代码%中的所有00-FF,甚至更好,%25

一个简单的解决方案是只编辑GUI中的相应命令(通过项目属性),而不是直接在.vcxproj或.props文件中编辑。这样,VS就会插入正确的转义码。在我的情况下,这是不可能的,因为命令被定义为用户宏(属性页:公共属性/用户宏)。我的命令跨越多行,但用户宏编辑器仅支持单行。

另一件要注意的事情是,它不仅取代百分号。其他符号具有特殊含义,也必须更换。 (这超出了XML实体,例如& -> &。)这是来自MSDN的list of special characters。字符是:% $ @ ' ; ? *。似乎没有必要一直替换所有这些,但如果你注意到时髦的行为,那么这是一个值得关注的事情。您可以尝试通过GUI输入这些字符,并查看VS如何以及是否在项目文件中转义它们。

其他要注意的字符尤其是分号。如果使用未转义的分号定义属性,如<MyPaths>DirA;DirB</MyPaths>,msbuild / VS将在内部将它们转换为换行符(好吧,或者将属性拆分为列表或其他内容)。但它仍然会在属性页中显示以分号分隔的路径!除非您单击属性旁边的下拉按钮并选择<Edit...>,否则它会将路径显示为列表或以换行符分隔!这在大多数情况下是完全不可见的,除非您设置的属性不是XML或GUI,而是reading the output of a command into a property。在这种情况下,如果您想要分号的效果,则命令必须输出换行符。否则你不会得到多条路径,而是一条带有分号的长路径。

答案 1 :(得分:1)

批处理文件通常位于北美和西欧国家的“ASCII”文件中,使用的是OEM代码页,如code page 850(OEM多语言拉丁语I)或code page 437(OEM US),而不是代码页{ {3}}通常用于单字节编码的文本文件。用于批处理文件的代码页取决于控制台中非Unicode文件的本地设置。如果批处理文件中只使用代码值小于128的字符,则代码页无关紧要,即批处理文件是真实的Windows-1252文件。

因此,请确保使用正确的代码页编辑批处理文件并将其另存为ASCII文件,而不是使用UTF-8,UTF-16 Little Endian或UTF-16 Big Endian作为Unicode文件。 Visual Studio的编辑器默认使用UTF-8编码来处理文件。这是批处理文件的错误编码。

字符«在代码页850的表中具有代码值174十进制(0xAB)。在代码页1252中,代码值174用于字符®,这表示您要以UTF-8编码的批处理文件字符输出(字符®<的代码值174也是如此) / strong>)或Windows-1252。

用于演示的简单批处理代码,存储为ANSI文件,代码页为Windows-1252。

@echo off
cls
echo This batch file was saved as ANSI file using code page Windows-1252.
echo.
echo Registered trademark symbol ® has code value 174 in Windows-1252.
echo.
echo But active code page is not Windows 1252 in console window.
echo.
chcp
echo.
echo Therefore the left guillemet character is output instead of registered
echo trademark symbol as this character has in code page 850 code value 174.
echo.
echo Press any key to continue ...
pause>nul

批处理文件适用于DOS / Windows,因此应使用回车符+换行符作为行终止符,而不仅仅是换行符(UNIX)或回车符(旧MAC)。

某些文本编辑器在活动文件的主应用程序窗口底部的状态栏中的某处显示行终止符类型和编码。