如何使用MSBuild在%PATH%中执行程序?

时间:2011-08-10 15:06:03

标签: msbuild msbuild-task

注意:我在这里使用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输出重定向和命令行参数不是问题。

2 个答案:

答案 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