diff options
author | Kartik Null Cating-Subramanian <ksubramanian@chef.io> | 2015-05-20 18:48:01 -0400 |
---|---|---|
committer | Kartik Null Cating-Subramanian <ksubramanian@chef.io> | 2015-06-09 14:20:42 -0400 |
commit | 02ea04af4dfbe228e07ed6668748a93512eeaddb (patch) | |
tree | 1e207941d8fe792e0076c0e7f27dd9cfd2b784d6 /distro | |
parent | a7b525b5d54169eedc8a95f3de134cc884da32c3 (diff) | |
download | chef-02ea04af4dfbe228e07ed6668748a93512eeaddb.tar.gz |
Release handles, set exit-code and handle errors.
Diffstat (limited to 'distro')
-rw-r--r-- | distro/powershell/chef/chef.psm1 | 56 |
1 files changed, 47 insertions, 9 deletions
diff --git a/distro/powershell/chef/chef.psm1 b/distro/powershell/chef/chef.psm1 index d8d475e872..6646226795 100644 --- a/distro/powershell/chef/chef.psm1 +++ b/distro/powershell/chef/chef.psm1 @@ -112,12 +112,13 @@ public enum StandardHandle : int public static class Kernel32 { [DllImport("kernel32.dll", SetLastError=true)] - public static extern int CreateProcess( + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool CreateProcess( string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES lpThreadAttributes, - bool bInheritHandles, + [MarshalAs(UnmanagedType.Bool)] bool bInheritHandles, CreationFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, @@ -125,10 +126,24 @@ public static class Kernel32 out PROCESS_INFORMATION lpProcessInformation); [DllImport("kernel32.dll", SetLastError=true)] - public static extern IntPtr GetStdHandle(StandardHandle nStdHandle); + public static extern IntPtr GetStdHandle( + StandardHandle nStdHandle); [DllImport("kernel32", SetLastError=true)] - public static extern int WaitForSingleObject(IntPtr hHandle, int dwMilliseconds); + public static extern int WaitForSingleObject( + IntPtr hHandle, + int dwMilliseconds); + + [DllImport("kernel32", SetLastError=true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool CloseHandle( + IntPtr hObject); + + [DllImport("kernel32", SetLastError=true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetExitCodeProcess( + IntPtr hProcess, + out int lpExitCode); } } "@ @@ -136,7 +151,7 @@ public static class Kernel32 function Run-ExecutableAndWait($AppPath, $ArgumentString) { # Use the Win32 API to create a new process and wait for it to terminate. - Load-Win32Bindings + $null = Load-Win32Bindings $si = New-Object Chef.STARTUPINFO $pi = New-Object Chef.PROCESS_INFORMATION @@ -156,10 +171,33 @@ function Run-ExecutableAndWait($AppPath, $ArgumentString) { $tSec.bInheritHandle = $true $success = [Chef.Kernel32]::CreateProcess($AppPath, $ArgumentString, [ref] $pSec, [ref] $tSec, $true, [Chef.CreationFlags]::NONE, [IntPtr]::Zero, $pwd, [ref] $si, [ref] $pi) - if ($success -eq 0) { - [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() - } else { - [Chef.Kernel32]::WaitForSingleObject($pi.hProcess, -1) + if (-Not $success) { + $reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() + throw "Unable to create process [$ArgumentString]. Error code $reason." + } + $waitReason = [Chef.Kernel32]::WaitForSingleObject($pi.hProcess, -1) + if ($waitReason -ne 0) { + if ($waitReason -eq -1) { + $reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() + throw "Could not wait for process to terminate. Error code $reason." + } else { + throw "WaitForSingleObject failed with return code $waitReason - it's impossible!" + } + } + $success = [Chef.Kernel32]::GetExitCodeProcess($pi.hProcess, [ref] $global:LASTEXITCODE) + if (-Not $success) { + $reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() + throw "Process exit code unavailable. Error code $reason." + } + $success = [Chef.Kernel32]::CloseHandle($pi.hProcess) + if (-Not $success) { + $reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() + throw "Unable to release process handle. Error code $reason." + } + $success = [Chef.Kernel32]::CloseHandle($pi.hThread) + if (-Not $success) { + $reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() + throw "Unable to release thread handle. Error code $reason." } } |