Powershell - закрывает Out-GridView через определенное время
Я хочу, чтобы Out-GridView закрывался через определенное время, например, через 10 секунд.
Не используется для Windows PowerShell.
Любой ответ помогает.
1 ответ
К сожалению, PowerShell не предлагает поиск и закрытие произвольных окон графического интерфейса, но вы можете использовать Add-Type
Командлет с ad-hoc-скомпилированным кодом C#, который в свою очередь использует объявления P/Invoke для доступа к Windows API.
Ниже приведен рабочий пример:
Он определяет отдельный заголовок окна для использования в
Out-GridView
вызвать так, чтобы окно (надеюсь) было однозначно расположено по его названию позже; также предполагается, что существует только одно окно с таким названием.- Чтобы сделать это более надежным, ограничив поиск окна тем же процессом,... потребовалось бы немного дополнительной работы.
Это создает фоновое задание, которое использует
Add-Member
определить статический вспомогательный класс с методом для закрытия окна по его заголовку и вызвать его по истечении заданного времени ожидания.Это вызывает
Out-GridView
синхронно (блокировка) с-Wait
, используя указанный заголовок окна. Если окно оставить открытым в течение указанного периода времени, фоновое задание автоматически закроет его.Удаляет фоновое задание после закрытия окна.
Примечание: если вам не нужно Out-GridView
звоните, чтобы быть синхронным, вам не обязательно нужна фоновая работа.
# 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