by Klaus Graefensteiner
8. July 2010 12:53
The Problem
This one cost me some hair. I had to write a script that would pass parameters to a .NET console application. The application used a command line parsing framework that uses the following notation:
/Parameter1:”Some string value” /Parameter2:”Some other value” etc.
An example command line would look like this:
ocp /in:”c:\my folder\my csv file.csv /out:”c:\my folder\the result.csv”
The following code snippets show a history of attempts. I created a simple application for debugging the command parameters that get passed by PowerShell. The application is called OCP (Output Command Line Parameters). The source code for this utility is attached together with the PowerShell script.
Try And Error
cd "C:\Users\Klaus\Documents\Visual Studio 2010\Projects\OCP\OCP\bin\Debug"
#Passes three arguments to OCP (expected)
./OCP this and that
#+++OUTPUT+++
#OCP-Parameter <this>
#OCP-Parameter <and>
#OCP-Parameter <that>
#I would expect one argument to be passed to OCP, but because of the two spaces in
#the excaped string I am getting 3 arguments
./OCP "/in:`"C:\My Test\Your Input.csv`""
#+++OUTPUT+++
#OCP-Parameter </in:C:\My>
#OCP-Parameter <Test\Your>
#OCP-Parameter <Input.csv>
#This one seems to work, but using the same command in CMD causes the split into 3 arguments again
./OCP "/in:C:\My Test\Your Input.csv"
#+++OUTPUT+++
#OCP-Parameter </in:C:\My Test\Your Input.csv>
$p = '"this and that"', "other"
./OCP $p
#+++OUTPUT+++
#OCP-Parameter <this and that>
#OCP-Parameter <other>
#Works as needed
$p = '/in:C:\My Test\Your Input.csv', "other"
./OCP $p
#+++OUTPUT+++
#OCP-Parameter </in:C:\My Test\Your Input.csv>
#OCP-Parameter <other>
#Doesn't work as expected
$p = '/in:"C:\My Test\Your Input.csv"', "other"
./OCP $p
#+++OUTPUT+++
#OCP-Parameter </in:C:\My>
#OCP-Parameter <Test\Your>
#OCP-Parameter <Input.csv>
#OCP-Parameter <other>
#Using start-process finally solved my problem completely
$result = start-process -filePath "C:\Users\Klaus\Documents\Visual Studio 2010\Projects\OCP\OCP\bin\Debug\ocp" -ArgumentList "/in:`"C:\My Test\Your Input.csv`"", "Other" -NoNewWindow -RedirectStandardError "error.txt" -RedirectStandardOutput "output.txt" -wait -passthru
$result.HasExited
$result.ExitCode
$output = get-content "output.txt"
$output
#+++OUTPUT+++
#OCP-Parameter </in:C:\My Test\Your Input.csv>
#OCP-Parameter <Other>
$ErrorMessage = get-content "error.txt"
$ErrorMessage
The Solution
Using the Start-Process command let finally provided the correct and expected results. In the process of getting to this result I used temporarily the following workaround: I converted the long file names with spaces into short DOS 8.3 file names.
Download
The command line parameter debugging console application and the test script can be downloaded here: PowerShellStartProcessStringCmdlineParamet
ers.zip
Ausblick
I am pretty sure that the command line parsing and passing system in PowerShell has a bug.