I want that a Out-GridView closes after a specific time, e.g after 10 seconds.
Not used to the windows powershell.
Any answer helps.
I want that a Out-GridView closes after a specific time, e.g after 10 seconds.
Not used to the windows powershell.
Any answer helps.
Unfortunately, PowerShell doesn't natively offer finding and closing arbitrary GUI windows, but you can use the Add-Type
cmdlet with ad hoc-compiled C# code that in turn uses P/Invoke declarations to access the Windows API.
The following is a working example:
It defines a distinct window title to use for the Out-GridView
call so that the window can be (hopefully) unambiguously located by its title later; also the assumption is that only one window by that title exists.
It creates a background job that uses Add-Member
to define a static helper class with a method for closing a window by its title, and calls it after a specifiable timeout.
It invokes Out-GridView
synchronously (blocking) with -Wait
, using the specified window title. If the window is left open for the specified timeout period, the background job will automatically close it.
It removes the background job after the window has closed.
Note: If you don't need the Out-GridView
call to be synchronous, you wouldn't necessarily need a background job.
# Define a distinct window title that you expect no other window to have.
$title = 'Close Me'
# Start a background job that closes the window after a specified timeout.
$job = Start-Job {
param($timeout, $title)
# Define a helper class that uses the Windows API to find and close windows.
Add-Type -Namespace same2u.net -Name WinUtil -MemberDefinition @'
// P/Invoke declarations for access to the Windows API.
[DllImport("user32.dll", SetLastError=true)]
private static extern IntPtr FindWindow(string lpszClass, string lpszWindow);
[DllImport("user32.dll", SetLastError=true)]
private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
const UInt32 WM_CLOSE = 0x0010;
// Returns the hWnd (window handle) of the first window that matches the
// specified title and, optionally, window class.
// If none is found, IntPtr.Zero is returned, which can you test for with -eq 0
public static IntPtr GetWindowHandle(string title, string className = null) {
// As a courtesy, we interpet '' as null, because passing null from
// PowerShell requires the non-obvious [nullstring]::value.
if (className == "") { className = null; }
return FindWindow(className, title);
}
// Closes the first window that matches the specified title and, optionally,
// window class. Returns true if a windows found and succesfully closed.
public static bool CloseWindow(string title, string className = null) {
bool ok = false;
// As a courtesy, we interpet '' as null, because passing null from
// PowerShell requires the non-obvious [nullstring]::value.
if (className == "") { className = null; }
IntPtr hwnd = FindWindow(className, title);
if (hwnd != IntPtr.Zero) {
SendMessage(hwnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
// !! SendMessage seemingly always returns 0. To determine success,
// !! we simply test if the window still exists.
ok = IntPtr.Zero == FindWindow(className, title);
}
return ok;
}
'@
Start-Sleep $timeout
$null = [same2u.net.WinUtil]::CloseWindow($title)
} -ArgumentList 3, $title
# Open an Out-GridView window synchronously.
# If you leave it open, the background job will close it after 3 seconds.
1..10 | Out-GridView -Title $title -Wait
# Remove the background job; -Force is needed in case the job hasn't finished yet
# (if you've closed the window manually before the timeout).
Remove-Job -Force $job