注意:我在这里使用Mercurial作为示例,因为这就是我现在正在尝试使用MSBuild。
但问题不仅限于Mercurial,它发生在我的%PATH%
变量中的某个外部程序中(例如我尝试使用PowerShell)。
所以我没有故意将Mercurial标签放在这个问题上,因为这不是关于Mercurial的!
我真正想做的事:
我希望我的构建脚本从我的Mercurial存储库中获取当前的修订版号并将其存储在一个文件中
从命令行执行此操作的最简单方法是:
hg id -i >rev.txt
Mercurial已安装在我的机器上,安装文件夹位于我的%PATH%
变量中
所以我可以从我的机器上的任何地方(直接从命令行或批处理文件)运行这一行,它只是起作用。
当我尝试从构建脚本运行此行时,会出现问题
我更改了.csproj文件的BeforeBuild
(或AfterBuild
)部分,如下所示:
<Target Name="AfterBuild">
<Exec Command="hg id -i >rev.txt"/>
</Target>
当我使用Visual Studio编译我的解决方案时,它可以工作,并且在.csproj所在的文件夹中创建了rev.txt文件。
但是当我使用MSBuild从命令行编译完全相同的解决方案时,构建失败并显示以下错误消息:
命令“hg id -i&gt; rev.txt”退出,代码为9009。
我用Google搜索“msbuild code 9009”并找到some solutions,但他们都建议提供可执行文件的完整路径。
当我这样做时,构建也成功与MSBuild。
但这对我来说不是一个可以接受的解决方案,因为我不能确定每个使用我的项目的人(包括构建服务器)都在同一文件夹中安装了Mercurial。
这正是%PATH%
的目的......
当我将<Exec Command="...
行直接放入构建脚本时,会发生同样的情况
如果我指定可执行文件的路径,它就可以工作
如果我没有指定路径,则不会。
有没有诀窍让MSBuild在%PATH%
变量中执行程序而不指定完整文件夹?
修改
@leppie:
输出重定向:
你的意思是我将命令的输出保存在命令中的文本文件中,而不是仅仅运行hg id -i
作为命令并使用输出参数或类似的东西来获取输出?
没有任何区别......当我省略>rev.txt
时,错误是相同的。
命令行参数:
不,它会抛出相同的错误,即使我将命令缩短为hg
(没有任何参数)。
不要忘记:如果我在Visual Studio中完全相同的.csproj文件中运行完全相同的Exec命令,或者如果我只是在命令中提供.exe文件的路径,那么一切正常。
所以IMO输出重定向和命令行参数不是问题。
答案 0 :(得分:1)
您是否尝试过mercurial / msbuild的扩展包? http://msbuildhg.codeplex.com/documentation
似乎有一个返回修订版ID的任务,这是你试图实现的没有?
<HgVersion LocalPath="$(MSBuildProjectDirectory)" Timeout="5000">
<Output TaskParameter="Revision" PropertyName="AssemblyRevision" />
</HgVersion>
答案 1 :(得分:1)
好的,我找到了解决办法 我不得不承认,这是PEBKAC的经典案例: - )
无论如何我会解释它,也许它会帮助那些犯同样错误的人:
基本上我所尝试的一切(以及James Woolfenden在他的回答中建议的内容)都会有效...如果我用来运行构建脚本的批处理文件看起来不像这样:
path="%windir%\Microsoft.net\Framework\v4.0.30319"
msbuild build.proj
是的,确实
我在这个批处理文件的持续时间内正在编辑%PATH%
变量,并且我覆盖它使用MSBuild的路径而不是追加它。
因此,当我的构建脚本尝试调用Mercurial时,它再也找不到了,因为它的位置不再位于%PATH%
变量中。
不知道为什么我之前没有看到这个。
正确的方法是追加 MSBuild路径,保持其他路径不变:
path=%path%;%windir%\Microsoft.net\Framework\v4.0.30319