开发者

How do I pass an equal sign when calling a batch script in Powershell?

We have a batch file that invokes our MSBuild-based build process. Syntax:

build App Target [ Additional MSBuild Arguments ]

Internally, it does this:

msbuild.exe %1.msbuild /t:%2 %3 %4 %5 %6 %7 %8 %9

Which results in calls to MSBuild that look like this:

msbuild.exe App.msbuild /t:Target

When any argument contains the equal sign, =, Powershell completely removes it. My batch script never sees it. This does not happen with the standard cmd.exe command prompt.

For example, if I call

build App Target "/p:Property=Value"

this is what gets passed to MSBuild:

msbuild.exe App.msmbuild /t:Target /p:Property Value

I expected this:

msbuild.exe App.msbuild /t:Target "/p:Property=Value"

I've tried the Powershell escape character, the standard Command Prompt escape character, and even stuff I made up:

开发者_如何学运维build App Target "/p:Property=Value"
build App Target '/p:Property=Value'
build App Target /p:Property^=Value
build App Target /p:Property`=Value
build App Target /p:Property==Value

None of it works. What do I do to get the equal sign to not be stripped out or removed?


I've seen this before and have found a way to trick it out. I wish I could explain what's going on in particular with the '=' but I cannot. In your situation I'm fairly certain the following will work if you want to pass properties to msbuild:

build App Target '"/p:Property=Value"' 

When echoed, this produces the following:

msbuild.exe App.msbuild /t:Target "/p:Property=Value"


With PowerShell 3 you can use --% to stop the normal parsing powershell does.

build --% App Target "/p:Property=Value"


I don't know if there's an easier answer (I think not) but you can solve the problem by using .Net's process class to invoke cmd.exe. Here's an example:

# use .NET Process class to run a batch file, passing it an argument that contains an equals sign. 
# This test script assumes the existence of a batch file "c:\temp\test.bat"
# that has this content:
#      echo %1
#      pause
$cmdLine =  $cmdLine =  '/c c:\temp\test.bat "x=1"'
$procStartInfo =  new-object System.Diagnostics.ProcessStartInfo("cmd", $cmdLine )
$proc = new-object System.Diagnostics.Process
$proc.StartInfo = $procStartInfo
$proc.Start();


Have you tried single quotes to force a literal interpretation?

Or: cmd /c 'msbuild.exe App.msbuild /t:Target "/p:Property=Value"'


It seems that only single-quote around double-quote might be the best for multiple scenario around windows environment. Following link from MS shows its support(or limitation) of equal sign http://support.microsoft.com/kb/35938 It is specific to Batch Files but it likely affect lots of other MS shell products.


The answer is that %2 becomes "/p:property" and %3 becomes "value".

Make this work in your batch file by using BOTH %2 and %3 and insert an = sign between them:

msbuild.exe %1.msbuild /t:%2=%3 %4 %5 %6 %7 %8 %9

and do not use the quote chars on the command line call. Use:

build App Target /p:property=value

For additional args with = signs just keep pairing them up.

I had the same issue with a simple batch file to run youtube-dl where the URL I pass has an = sign in it. solved as :

@echo off
REM YTDL audio only
echo %1=%2
youtube-dl -f bestaudio --extract-audio --audio-format mp3 --audio-quality 0 %1=%2
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜