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



注意:我在这里使用Mercurial作为一个例子,因为这是我现在试图与MSBuild一起工作的东西。
但问题不仅限于Mercurial,它发生在我的%PATH%变量中的每个外部程序(例如,我尝试了与PowerShell相同)。
所以我没有故意在这个问题上加上水星的标签,因为这与水星无关!

我真正想做的是:
我希望我的构建脚本从我的Mercurial存储库中获取当前版本号并将其存储在一个文件中。
从命令行执行此操作的最简单方法是:

hg id -i >rev.txt

我的机器上安装了Mercurial,安装文件夹在我的%PATH%变量中。
因此,我可以在我的机器上的任何地方运行这行代码(直接从命令行,或者从批处理文件),并且它可以正常工作。

当我尝试从构建脚本运行这一行时,问题发生了。
我更改了.csproj文件的BeforeBuild(或AfterBuild)部分,如下所示:

<Target Name="AfterBuild">
     <Exec Command="hg id -i >rev.txt"/>
</Target>

当我用Visual Studio编译我的解决方案时,它工作了,rev.txt文件在我的。csproj所在的文件夹中创建。

但是当我用MSBuild从命令行编译完全相同的解决方案时,构建失败,并出现以下错误消息:

命令"hg id -i>rev.txt"退出,代码为9009。

我搜索了"msbuild code 9009"并找到了一些解决方案,但他们都建议提供可执行文件的完整路径。
当我这样做时,MSBuild也会成功构建。
但这对我来说不是一个可接受的解决方案,因为我不能确定使用我的项目的每个人(包括构建服务器)都在同一个文件夹中安装了Mercurial。
这就是%PATH%的作用……

当我将<Exec Command="...行直接放入构建脚本中时,也会发生同样的情况。
如果我指定了可执行文件的路径,它就会工作。
如果我不指定路径,它就不会。

是否有任何技巧使MSBuild在我的%PATH%变量中执行程序而不指定完整的文件夹?


编辑:

@leppie:

输出重定向:
你的意思是我保存命令的输出在命令内的文本文件中,而不是只是运行hg id -i作为命令并使用输出参数或类似的东西来获得输出?
没有什么区别……当我省略>rev.txt时,错误是相同的。

命令行参数:
不,它抛出相同的错误,即使我缩短命令为hg(没有任何参数)。

不要忘记:如果我在Visual Studio中完全相同的。csproj文件中运行完全相同的Exec命令,或者如果我只是在命令中提供。exe文件的路径,一切都工作。
所以IMO输出重定向和命令行参数不会是问题。

您尝试过mercurial/msbuild的扩展包吗?http://msbuildhg.codeplex.com/documentation

似乎有一个返回修订id的任务,这是你想要实现的吗?

<HgVersion LocalPath="$(MSBuildProjectDirectory)" Timeout="5000">
     <Output TaskParameter="Revision" PropertyName="AssemblyRevision" />
</HgVersion>

好了,我找到解决办法了。
我不得不承认,这是一个典型的PEBKAC案例:-)

我还是解释一下,也许能帮助到犯同样错误的人:

基本上我所尝试的一切(加上James Woolfenden在他的回答中建议的)都是有效的…如果我用来运行构建脚本的批处理文件不是这样就好了:

path="%windir%Microsoft.netFrameworkv4.0.30319"
msbuild build.proj

是的,没错。我在这个批处理文件的持续时间内编辑%PATH%变量,我用MSBuild的路径覆盖它,而不仅仅是附加它。

所以当我的构建脚本试图调用Mercurial时,它再也找不到它了,因为它的位置不再在%PATH%变量中了。
不知道为什么我之前没有看到这个

正确的方法是追加的MSBuild路径,保持其他路径不变:

path=%path%;%windir%Microsoft.netFrameworkv4.0.30319

相关内容

最新更新