* changed RunCommand result from Tuple to CommandResult for easier future extensibility
* moved Win32 Dictionary->multi-null-string environment munging into C#
(cherry picked from commit 0e70057f561875c40d3d5285fd5f0dfcbe8087e6)
... | ... |
@@ -3,6 +3,7 @@ |
3 | 3 |
|
4 | 4 |
$process_util = @" |
5 | 5 |
using System; |
6 |
+using System.Collections; |
|
6 | 7 |
using System.IO; |
7 | 8 |
using System.Linq; |
8 | 9 |
using System.Runtime.InteropServices; |
... | ... |
@@ -210,7 +211,14 @@ namespace Ansible |
210 | 210 |
return sbOut.ToString(); |
211 | 211 |
} |
212 | 212 |
|
213 |
- public static Tuple<string, string, uint> RunCommand(string lpApplicationName, string lpCommandLine, string lpCurrentDirectory, string stdinInput, string environmentBlock) |
|
213 |
+ public class CommandResult |
|
214 |
+ { |
|
215 |
+ public string StandardOut { get; internal set; } |
|
216 |
+ public string StandardError { get; internal set; } |
|
217 |
+ public uint ExitCode { get; internal set; } |
|
218 |
+ } |
|
219 |
+ |
|
220 |
+ public static CommandResult RunCommand(string lpApplicationName, string lpCommandLine, string lpCurrentDirectory, string stdinInput, IDictionary environment) |
|
214 | 221 |
{ |
215 | 222 |
UInt32 startup_flags = CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE | EXTENDED_STARTUPINFO_PRESENT; |
216 | 223 |
STARTUPINFOEX si = new STARTUPINFOEX(); |
... | ... |
@@ -277,11 +285,21 @@ namespace Ansible |
277 | 277 |
// string here, we need to convert it |
278 | 278 |
if (lpCurrentDirectory == "") |
279 | 279 |
lpCurrentDirectory = null; |
280 |
- |
|
280 |
+ |
|
281 |
+ StringBuilder environmentString = null; |
|
282 |
+ |
|
283 |
+ if(environment != null && environment.Count > 0) |
|
284 |
+ { |
|
285 |
+ environmentString = new StringBuilder(); |
|
286 |
+ foreach (DictionaryEntry kv in environment) |
|
287 |
+ environmentString.AppendFormat("{0}={1}\0", kv.Key, kv.Value); |
|
288 |
+ environmentString.Append('\0'); |
|
289 |
+ } |
|
290 |
+ |
|
281 | 291 |
// Create the environment block if set |
282 | 292 |
IntPtr lpEnvironment = IntPtr.Zero; |
283 |
- if (environmentBlock != "") |
|
284 |
- lpEnvironment = Marshal.StringToHGlobalUni(environmentBlock); |
|
293 |
+ if (environmentString != null) |
|
294 |
+ lpEnvironment = Marshal.StringToHGlobalUni(environmentString.ToString()); |
|
285 | 295 |
|
286 | 296 |
// Create new process and run |
287 | 297 |
StringBuilder argument_string = new StringBuilder(lpCommandLine); |
... | ... |
@@ -316,7 +334,12 @@ namespace Ansible |
316 | 316 |
GetProcessOutput(stdout, stderr, out stdout_str, out stderr_str); |
317 | 317 |
uint rc = GetProcessExitCode(pi.hProcess); |
318 | 318 |
|
319 |
- return Tuple.Create(stdout_str, stderr_str, rc); |
|
319 |
+ return new CommandResult |
|
320 |
+ { |
|
321 |
+ StandardOut = stdout_str, |
|
322 |
+ StandardError = stderr_str, |
|
323 |
+ ExitCode = rc |
|
324 |
+ }; |
|
320 | 325 |
} |
321 | 326 |
|
322 | 327 |
private static void GetProcessOutput(StreamReader stdoutStream, StreamReader stderrStream, out string stdout, out string stderr) |
... | ... |
@@ -361,7 +384,7 @@ Function Load-CommandUtils { |
361 | 361 |
# [Ansible.CommandUtil]::RunCommand(string lpApplicationName, string lpCommandLine, string lpCurrentDirectory, string stdinInput, string environmentBlock) |
362 | 362 |
# |
363 | 363 |
# there are also numerous P/Invoke methods that can be called if you are feeling adventurous |
364 |
- Add-Type -TypeDefinition $process_util -IgnoreWarnings |
|
364 |
+ Add-Type -TypeDefinition $process_util -IgnoreWarnings -Debug:$false |
|
365 | 365 |
} |
366 | 366 |
|
367 | 367 |
Function Get-ExecutablePath($executable, $directory) { |
... | ... |
@@ -412,29 +435,14 @@ Function Run-Command { |
412 | 412 |
$arguments = [Ansible.CommandUtil]::ParseCommandLine($command) |
413 | 413 |
$executable = Get-ExecutablePath -executable $arguments[0] -directory $working_directory |
414 | 414 |
|
415 |
- # set the extra environment variables |
|
416 |
- $environment_string = $null |
|
417 |
- if ($environment.Count -gt 0) { |
|
418 |
- $environment_string = "" |
|
419 |
- } |
|
420 |
- foreach ($environment_entry in $environment.GetEnumerator()){ |
|
421 |
- $environment_key = $environment_entry.Name |
|
422 |
- $environment_value = $environment_entry.Value |
|
423 |
- $environment_string += "$environment_key=$environment_value`0" |
|
424 |
- } |
|
425 |
- if ($environment_string) { |
|
426 |
- $environment_string += "`0" |
|
427 |
- } |
|
428 |
- |
|
429 | 415 |
# run the command and get the results |
430 |
- $command_result = [Ansible.CommandUtil]::RunCommand($executable, $command, $working_directory, $stdin, $environment_string) |
|
416 |
+ $command_result = [Ansible.CommandUtil]::RunCommand($executable, $command, $working_directory, $stdin, $environment) |
|
431 | 417 |
|
432 |
- # RunCommand returns a tuple, we will convert to a hashtable |
|
433 | 418 |
return ,@{ |
434 | 419 |
executable = $executable |
435 |
- stdout = $command_result.Item1 |
|
436 |
- stderr = $command_result.Item2 |
|
437 |
- rc = $command_result.Item3 |
|
420 |
+ stdout = $command_result.StandardOut |
|
421 |
+ stderr = $command_result.StandardError |
|
422 |
+ rc = $command_result.ExitCode |
|
438 | 423 |
} |
439 | 424 |
} |
440 | 425 |
|