如何使用MSBuild在%PATH%中执行程序? [英] How can I execute programs in my %PATH% with MSBuild?

查看:573
本文介绍了如何使用MSBuild在%PATH%中执行程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:我在这里以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> rev.txt",代码为9009.

我用Google搜索"msbuild代码9009",发现一些 行放入构建脚本中时,也会发生同样的情况.
如果我指定了可执行文件的路径,它将起作用.
如果我未指定路径,则不会.

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


@leppie:

输出重定向:
您的意思是这样的事实,我将命令的输出保存在命令中的文本文件中 ,而不是仅将hg id -i作为命令运行并使用输出参数或类似的东西来获取输出?
没什么区别...我省略>rev.txt时的错误是相同的.

命令行参数:
不,即使我将命令缩短为hg(不带任何参数),它也会引发相同的错误.

别忘了:如果我在Visual Studio中的完全相同的.csproj文件中运行完全相同的Exec命令,或者如果我只是在命令中提供了.exe文件的路径,那么一切都会正常.
因此,IMO输出重定向和命令行args不会成为问题.

解决方案

好的,我找到了解决方案.
我不得不承认,这是
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

Note: I'm using Mercurial as an example here, because that's what I'm trying to get to work with MSBuild right now.
But the problem is not limited to Mercurial, it happens with every external program that is somewhere in my %PATH% variable (I tried the same with PowerShell, for example).
So I didn't put the Mercurial tag on this question on purpose, because this is not about Mercurial!

What I actually want to do:
I want my build script to get the current revision number from my Mercurial repository and store it in a file.
The simplest way to do this from the command line is:

hg id -i >rev.txt

Mercurial is installed on my machine and the installation folder is in my %PATH% variable.
So I can run this line from anywhere on my machine (directly from the command line, or from a batch file), and it just works.

The problem occurs when I try to run this line from my build script.
I change the BeforeBuild (or AfterBuild) section of my .csproj file as follows:

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

When I compile my solution with Visual Studio, it works and the rev.txt file is created in the folder where my .csproj is.

But when I compile the exact same solution from the command line with MSBuild, the build fails with the following error message:

The command "hg id -i >rev.txt" exited with code 9009.

I googled "msbuild code 9009" and found some solutions, but all of them propose to provide the full path to the executable.
When I do this, the build succeeds with MSBuild as well.
But this is not an acceptable solution for me, because I can't be sure that everyone using my project (including the build server) has installed Mercurial in the exact same folder.
That's exactly what %PATH% is for...

The same happens when I put the <Exec Command="... line directly into the build script.
If I specify the path to the executable, it works.
If I don't specify the path, it doesn't.

Is there any trick to make MSBuild execute programs in my %PATH% variable without specifying the complete folder?


EDIT:

@leppie:

Output redirection:
You mean the fact that I save the output of my command in a text file inside the command , instead of just running hg id -i as a command and using an output parameter or something like that to get the output?
Doesn't make any difference...the error is the same when I omit >rev.txt.

Command line args:
No, it throws the same error, even if I shorten the command to just hg (without any parameters).

Don't forget: if I run the exact same Exec command in the exact same .csproj file from Visual Studio, or if I just provide the path to the .exe file in the command, everything works.
So IMO output redirection and command line args can't be the problem.

解决方案

Okay, I found the solution.
I have to admit, it was a classic case of PEBKAC :-)

I'll explain it anyway, maybe it will help someone who made the same mistake:

Basically everything I have tried (plus what James Woolfenden suggested in his answer) would have been worked...if only the batch file that I use to run the build script wouldn't have looked like this:

path="%windir%\Microsoft.net\Framework\v4.0.30319"

msbuild build.proj

Yes, exactly.
I'm editing the %PATH% variable for the duration of this batch file, and I'm overwriting it with the path to MSBuild instead of just appending it.

So when my build script tries to call Mercurial, it can't find it anymore because its location is not in the %PATH% variable anymore.
No idea why I didn't see this before.

The correct way would be to append the MSBuild path, leaving the other paths intact:

path=%path%;%windir%\Microsoft.net\Framework\v4.0.30319

这篇关于如何使用MSBuild在%PATH%中执行程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆