문제

I would like to use Powershell 2.0 to script the creation of an application manifest using Microsoft's Manifest Generation and Editing tool (mage). Specifically, I would like to be able to pass dynamically specified parameter values to the mage command (e.g. read from xml or some other source).

Although I can accomplish this using invoke-expression, I would prefer to avoid it is regarded as a less secure option (i.e. vulnerable to "powershell injection attacks").

Here is what I know.

This succeeds with the message "application.exe.manifest successfully created":

& "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\mage.exe" -New Application

This does not succeed with the message "The first argument must be one of the following: -New, -Update, -Sign" (which is a mage, not powershell, error message):

$params = "-New Application"

& "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\mage.exe" $params

How can I pass the $params value to the mage command so it is successfully interpreted by mage?

도움이 되었습니까?

해결책

It is easy with $params defined as an array, one parameter per array item:

# define $params as an array
$params = "-New", "Application"

# and pass this array in, just as you tried before
& "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\mage.exe" $params

Ditto with $params dynamically built in a few steps:

$params = @()
...
$params += '-New'
...
$params += 'Application'
...
& "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\mage.exe" $params

This way is often overlooked but it is very handy, it allows easy dynamic composition of complex command lines for native applications.

P.S. And we do not have to care of spaces in parameter values, we use values in the parameter array as they are, no extra " needed.

다른 팁

Start-Process

There are more ways how to do that. First is via Start-Process:

$p = '-h 3 google.com'
start-process tracert -arg $p

New window pops up. If you would like to run the process inside the console, just run it with -NoNewWindow

$p = '-h 3 google.com'
start-process tracert -arg $p -nonew

$params = "-New Application"
start-process "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\mage.exe" -arg $params -nonew

Invoke-Expression

Invoke-Expression could help as well. But it is tricky, because you have spaces in path to your executable. This works, because there is no space in the path:

$p = '-h 3 google.com'
invoke-expression "tracert $p"

But if there is a space, you need to use & inside:

$params = "-New Application"
Invoke-Expression "& ""C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\mage.exe"" $params"

Note that "& ""C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\mage.exe"" $params" is expanded to this:

& "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\mage.exe" -New Application

which is what you wanted. But if there is again a space in one of the parameters, then again.. you need to quote it:

$file1 = 'c:\test path\file1.txt'
$file2 = 'c:\test path\file2.txt'
$params = """$file1"" ""$file2"""
Invoke-Expression "& someexecutable $params"

The parsing is quite tricky :|

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top