У меня есть сценарий, который представляет использование результатов out-gridview
. Вот простой пример:
"hello world" | out-gridview
Когда я выполню Выполнение использования сценария с PowerShell, оно откроет gridview и сразу закроет его после того, как оно открыто. (Я думаю, что это вызвано тем, что gridview не модален и концы сценария.)
Как заставить PowerShell ожидать, пока gridview вручную не закрывается?
Вы можете либо запустить PowerShell.exe с -NOEXIT
или попробуйте:
"hello world" | out-gridview
Read-Host "press enter to exit"
Обновлено:
Out-GridView неблокирует, поэтому, если вы хотите проверить для него, чтобы выйти, вы должны прибегать к некоторому низкоуровневым API-APIS Win32. Следующий код работает в ISE (не проверил его в хосте консоли). Также он имеет ограничение - в основном ищет любое окно, связанное с процессом HOST, кроме главного окна хоста, чтобы уйти. В этот момент он вернется. Оказывается, out-gridview не ребенок главного окна, а его подпись не последовательно (gps | out-gridview или gps | ogv или gps | <Любые псевдонима, которые вы составляете>
):
$src = @'
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
namespace Utils
{
public delegate bool Win32Callback(IntPtr hwnd, IntPtr lParam);
public class WindowHelper
{
private const int PROCESS_QUERY_LIMITED_INFORMATION = 0x1000;
private IntPtr _mainHwnd;
private IntPtr _ogvHwnd;
private IntPtr _poshProcessHandle;
private int _poshPid;
private bool _ogvWindowFound;
public WindowHelper()
{
Process process = Process.GetCurrentProcess();
_mainHwnd = process.MainWindowHandle;
_poshProcessHandle = process.Handle;
_poshPid = process.Id;
}
public void WaitForOutGridViewWindowToClose()
{
do
{
_ogvWindowFound = false;
EnumChildWindows(IntPtr.Zero, EnumChildWindowsHandler,
IntPtr.Zero);
Thread.Sleep(500);
} while (_ogvWindowFound);
}
[DllImport("User32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(
IntPtr parentHandle, Win32Callback callback, IntPtr lParam);
[DllImport("Oleacc.dll")]
public static extern IntPtr GetProcessHandleFromHwnd(IntPtr hwnd);
[DllImport("Kernel32.dll")]
public static extern int GetProcessId(IntPtr handle);
[DllImport("Kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DuplicateHandle(
IntPtr hSourceProcessHandle,
IntPtr hSourceHandle,
IntPtr hTargetProcessHandle,
out IntPtr lpTargetHandle,
int dwDesiredAccess,
bool bInheritHandle,
int dwOptions);
[DllImport("Kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr handle);
[DllImport("Kernel32.dll")]
public static extern int GetLastError();
private bool EnumChildWindowsHandler(IntPtr hwnd, IntPtr lParam)
{
if (_ogvHwnd == IntPtr.Zero)
{
IntPtr hProcess = GetProcessHandleFromHwnd(hwnd);
IntPtr hProcessDup;
if (!DuplicateHandle(hProcess, hProcess, _poshProcessHandle,
out hProcessDup,
PROCESS_QUERY_LIMITED_INFORMATION,
false, 0))
{
Console.WriteLine("Dup process handle {0:X8} error: {1}",
hProcess.ToInt32(), GetLastError());
return true;
}
int processId = GetProcessId(hProcessDup);
if (processId == 0)
{
Console.WriteLine("GetProcessId error:{0}",
GetLastError());
return true;
}
if (processId == _poshPid)
{
if (hwnd != _mainHwnd)
{
_ogvHwnd = hwnd;
_ogvWindowFound = true;
CloseHandle(hProcessDup);
return false;
}
}
CloseHandle(hProcessDup);
}
else if (hwnd == _ogvHwnd)
{
_ogvWindowFound = true;
return false;
}
return true;
}
}
}
'@
Add-Type -TypeDefinition $src
Get-Process | Out-GridView
$helper = new-object Utils.WindowHelper
$helper.WaitForOutGridViewWindowToClose()
"Done!!!!"