无法恢复使用 ShowWindow 隐藏的 windows
Unable to restore windows hidden with ShowWindow
我在脚本中有以下类型定义:
Add-Type -TypeDefinition @'
namespace Win32
{
//https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx
public static class Functions
{
[System.Runtime.InteropServices.DllImport("User32.dll", EntryPoint="ShowWindow")]
public static extern bool SW(System.IntPtr hWnd, Win32.SW nCmdShow);
}
public enum SW
{
HIDE = 0,
SHOW_NORMAL = 1,
SHOW_MINIMIZED = 2,
MAXIMIZE = 3,
SHOW_MAXIMIZED = 3,
SHOW_NO_ACTIVE = 4,
SHOW = 5,
MINIMIZE = 6,
SHOW_MIN_NO_ACTIVE = 7,
SHOW_NA = 8,
RESTORE = 9,
SHOW_DEFAULT = 10,
FORCE_MINIMIZE = 11
}
}
'@
其中的一切都有效,例如:
[Win32.Functions]::SW((Get-Process -Name powershell).MainWindowHandle, [Win32.SW]::SHOW_DEFAULT)
但是,当我使用[Win32.SW]::HIDE
时,我完全无法恢复那个window。每个选项都失败了,我得到 false
returns。文档中是否缺少某些内容或 SW_HIDE
的某个功能导致无法恢复?
我的最终目标是在自扩展 .cmd
->.ps1
脚本中创建一些 WPF GUI,创建伪可执行文件并隐藏遗留的 powershell window(可能会根据脚本操作恢复)。
我看到的是您是通过检查进程的名称来指代进程的。这可能有点棘手,因为可能 运行 具有相同名称的多个进程。因此,如果您要隐藏当前的 PowerShell window 并且希望稍后恢复它,请使用其 PID 而不是名称来引用它。可以在下面找到可以用作示例的代码。
Add-Type -TypeDefinition @'
namespace Win32
{
//https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx
public static class Functions
{
[System.Runtime.InteropServices.DllImport("User32.dll", EntryPoint="ShowWindow")]
public static extern bool SW(System.IntPtr hWnd, Win32.SW nCmdShow);
}
public enum SW
{
HIDE = 0,
SHOW_NORMAL = 1,
SHOW_MINIMIZED = 2,
MAXIMIZE = 3,
SHOW_MAXIMIZED = 3,
SHOW_NO_ACTIVE = 4,
SHOW = 5,
MINIMIZE = 6,
SHOW_MIN_NO_ACTIVE = 7,
SHOW_NA = 8,
RESTORE = 9,
SHOW_DEFAULT = 10,
FORCE_MINIMIZE = 11
}
}
'@
. ([ScriptBlock]::Create('using namespace Win32'))
$mainWindowHandle = (Get-Process -ID $PID).MainWindowHandle
[Functions]::SW($mainWindowHandle, [SW]::HIDE)
# Sleep for 5 seconds to prove it working
Start-Sleep -Seconds 5
[Functions]::SW($mainWindowHandle, [SW]::SHOW_DEFAULT)
请确保 运行 在最后一个命令之后至少有一个空换行符,否则它不会被执行并且你的 windows 将永远不会弹出 ;)
希望对您有所帮助!
问题是.MainWindowHandle
不再有效而window被隐藏[1]
,因此 "unhide" window 的尝试失败。
只需缓存 HWND 并在"unhiding" 调用中使用缓存的值:
# Also consider Get-Process -ID $PID, as in Stanislav's answer, to avoid ambiguity
# if multiple PowerShell processes exist.
$hWnd = (Get-Process -Name PowerShell).MainWindowHandle
# ... hide window and do stuff
# Unhide, using the *cached* HWND:
[Win32.Functions]::SW($hWnd, [Win32.SW]::SHOW_DEFAULT)
顺便说一句:ShowWindow()
Windows API function(此处别名为 SW
)
returns 一个布尔值,它不反映 成功 ,但 window 之前是否被隐藏 ($False
) 或不 ($True
).
[1]属性类型为[System.IntPtr]
,值为0
,window隐藏
我在脚本中有以下类型定义:
Add-Type -TypeDefinition @'
namespace Win32
{
//https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx
public static class Functions
{
[System.Runtime.InteropServices.DllImport("User32.dll", EntryPoint="ShowWindow")]
public static extern bool SW(System.IntPtr hWnd, Win32.SW nCmdShow);
}
public enum SW
{
HIDE = 0,
SHOW_NORMAL = 1,
SHOW_MINIMIZED = 2,
MAXIMIZE = 3,
SHOW_MAXIMIZED = 3,
SHOW_NO_ACTIVE = 4,
SHOW = 5,
MINIMIZE = 6,
SHOW_MIN_NO_ACTIVE = 7,
SHOW_NA = 8,
RESTORE = 9,
SHOW_DEFAULT = 10,
FORCE_MINIMIZE = 11
}
}
'@
其中的一切都有效,例如:
[Win32.Functions]::SW((Get-Process -Name powershell).MainWindowHandle, [Win32.SW]::SHOW_DEFAULT)
但是,当我使用[Win32.SW]::HIDE
时,我完全无法恢复那个window。每个选项都失败了,我得到 false
returns。文档中是否缺少某些内容或 SW_HIDE
的某个功能导致无法恢复?
我的最终目标是在自扩展 .cmd
->.ps1
脚本中创建一些 WPF GUI,创建伪可执行文件并隐藏遗留的 powershell window(可能会根据脚本操作恢复)。
我看到的是您是通过检查进程的名称来指代进程的。这可能有点棘手,因为可能 运行 具有相同名称的多个进程。因此,如果您要隐藏当前的 PowerShell window 并且希望稍后恢复它,请使用其 PID 而不是名称来引用它。可以在下面找到可以用作示例的代码。
Add-Type -TypeDefinition @'
namespace Win32
{
//https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx
public static class Functions
{
[System.Runtime.InteropServices.DllImport("User32.dll", EntryPoint="ShowWindow")]
public static extern bool SW(System.IntPtr hWnd, Win32.SW nCmdShow);
}
public enum SW
{
HIDE = 0,
SHOW_NORMAL = 1,
SHOW_MINIMIZED = 2,
MAXIMIZE = 3,
SHOW_MAXIMIZED = 3,
SHOW_NO_ACTIVE = 4,
SHOW = 5,
MINIMIZE = 6,
SHOW_MIN_NO_ACTIVE = 7,
SHOW_NA = 8,
RESTORE = 9,
SHOW_DEFAULT = 10,
FORCE_MINIMIZE = 11
}
}
'@
. ([ScriptBlock]::Create('using namespace Win32'))
$mainWindowHandle = (Get-Process -ID $PID).MainWindowHandle
[Functions]::SW($mainWindowHandle, [SW]::HIDE)
# Sleep for 5 seconds to prove it working
Start-Sleep -Seconds 5
[Functions]::SW($mainWindowHandle, [SW]::SHOW_DEFAULT)
请确保 运行 在最后一个命令之后至少有一个空换行符,否则它不会被执行并且你的 windows 将永远不会弹出 ;)
希望对您有所帮助!
问题是.MainWindowHandle
不再有效而window被隐藏[1]
,因此 "unhide" window 的尝试失败。
只需缓存 HWND 并在"unhiding" 调用中使用缓存的值:
# Also consider Get-Process -ID $PID, as in Stanislav's answer, to avoid ambiguity
# if multiple PowerShell processes exist.
$hWnd = (Get-Process -Name PowerShell).MainWindowHandle
# ... hide window and do stuff
# Unhide, using the *cached* HWND:
[Win32.Functions]::SW($hWnd, [Win32.SW]::SHOW_DEFAULT)
顺便说一句:ShowWindow()
Windows API function(此处别名为 SW
)
returns 一个布尔值,它不反映 成功 ,但 window 之前是否被隐藏 ($False
) 或不 ($True
).
[1]属性类型为[System.IntPtr]
,值为0
,window隐藏