You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过主窗口标题恢复VirtualBox虚拟机窗口的PowerShell问题

问题:无法通过PowerShell恢复含特定标题的VirtualBox虚拟机窗口

在多虚拟机环境下,Oracle VirtualBox的所有虚拟机进程名均为VirtualBoxVM,无法通过进程名恢复最小化窗口,因此需要借助唯一属性mainWindowTitle来实现。编写的PowerShell脚本执行后无错误提示,但仅出现短暂闪屏,目标窗口仍保持最小化状态。需恢复的窗口标题包含DC2,完整标题为DC2 [Running] - Oracle VM VirtualBox,无论使用完整标题还是部分标题均无效。

原始PowerShell脚本

Clear-Host
Function Set-WindowStyle 
{
    param
    (
        [Parameter()]
        [ValidateSet('FORCEMINIMIZE', 'HIDE', 'MAXIMIZE', 'MINIMIZE', 'RESTORE', 
            'SHOW', 'SHOWDEFAULT', 'SHOWMAXIMIZED', 'SHOWMINIMIZED', 
            'SHOWMINNOACTIVE', 'SHOWNA', 'SHOWNOACTIVATE', 'SHOWNORMAL')]
        $Style = 'SHOW',
        [Parameter()]
        $MainWindowHandle = (Get-Process -Id $pid).MainWindowHandle
    )

    $WindowStates = @{
        FORCEMINIMIZE = 11; HIDE = 0
        MAXIMIZE = 3; MINIMIZE = 6
        RESTORE = 9; SHOW = 5
        SHOWDEFAULT = 10; SHOWMAXIMIZED = 3
        SHOWMINIMIZED = 2; SHOWMINNOACTIVE = 7
        SHOWNA = 8; SHOWNOACTIVATE = 4
        SHOWNORMAL = 1
    }
    Write-Verbose ("Set Window Style {1} on handle {0}" -f $MainWindowHandle, $($WindowStates[$style]))

    $Win32ShowWindowAsync = Add-Type –memberDefinition @" 
    [DllImport("user32.dll")] 
    public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
"@ -name "Win32ShowWindowAsync" -namespace Win32Functions –passThru

    $Win32ShowWindowAsync::ShowWindowAsync($MainWindowHandle, $WindowStates[$Style]) | Out-Null
}

# Usage

# Minimize a running process window
#Get-Process -Name Taskmgr | %{Set-WindowStyle MINIMIZE $PSItem.MainWindowHandle}
#Get-Process -Name DC2* | %{Set-WindowStyle MINIMIZE $PSItem.MainWindowHandle}

# Restore a running process window - the last window called will be topmost
#Get-Process -Name DC2 | %{Set-WindowStyle RESTORE $PSItem.MainWindowHandle}
#Get-Process | Where-Object {$_.mainWindowTitle} | Format-Table Id, Name, mainWindowtitle -AutoSize
Get-Process | Where-Object {$_.MainWindowTitle -Contains "DC2"} | %{Set-WindowStyle RESTORE $PSItem.MainWindowHandle}

当前所有窗口标题输出

PS C:\Users\Admin1> Get-Process | Where-Object {$_.mainWindowTitle} | Format-Table Id, Name, mainWindowtitle -AutoSize

   Id Name           MainWindowTitle                                                                                                       
   -- ----           ---------------                                                                                                       
 9668 powershell_ise Windows PowerShell ISE                                                                                                
 5152 ServerManager  Server Manager                                                                                                        
 2504 VirtualBoxVM   CentOS2 [Running] - Oracle VM VirtualBox                                                                              
 4468 VirtualBoxVM   WIN10 [Running] - Oracle VM VirtualBox                                                                                                                                                            
 8812 VirtualBoxVM   DC2 [Running] - Oracle VM VirtualBox                                                                                  
 9028 VirtualBoxVM   MGMT1 [Running] - Oracle VM VirtualBox                                                                                
10252 VirtualBoxVM   CentOS1 [Running] - Oracle VM VirtualBox                                                                              
10752 VirtualBoxVM   ADFS1 [Running] - Oracle VM VirtualBox

解决方案

问题根源

脚本中使用了-Contains操作符,该操作符用于检查集合是否包含指定元素,而非判断字符串是否包含子串。针对单个字符串的子串匹配,应使用-Like或-Match操作符。

修正后的脚本

Clear-Host
Function Set-WindowStyle 
{
    param
    (
        [Parameter()]
        [ValidateSet('FORCEMINIMIZE', 'HIDE', 'MAXIMIZE', 'MINIMIZE', 'RESTORE', 
            'SHOW', 'SHOWDEFAULT', 'SHOWMAXIMIZED', 'SHOWMINIMIZED', 
            'SHOWMINNOACTIVE', 'SHOWNA', 'SHOWNOACTIVATE', 'SHOWNORMAL')]
        $Style = 'SHOW',
        [Parameter()]
        $MainWindowHandle = (Get-Process -Id $pid).MainWindowHandle
    )

    $WindowStates = @{
        FORCEMINIMIZE = 11; HIDE = 0
        MAXIMIZE = 3; MINIMIZE = 6
        RESTORE = 9; SHOW = 5
        SHOWDEFAULT = 10; SHOWMAXIMIZED = 3
        SHOWMINIMIZED = 2; SHOWMINNOACTIVE = 7
        SHOWNA = 8; SHOWNOACTIVATE = 4
        SHOWNORMAL = 1
    }
    Write-Verbose ("Set Window Style {1} on handle {0}" -f $MainWindowHandle, $($WindowStates[$style]))

    $Win32ShowWindowAsync = Add-Type –memberDefinition @" 
    [DllImport("user32.dll")] 
    public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
"@ -name "Win32ShowWindowAsync" -namespace Win32Functions –passThru

    $Win32ShowWindowAsync::ShowWindowAsync($MainWindowHandle, $WindowStates[$Style]) | Out-Null
}

# 恢复标题包含DC2的VirtualBox窗口
Get-Process | Where-Object {$_.MainWindowTitle -like "*DC2*"} | ForEach-Object {Set-WindowStyle RESTORE $PSItem.MainWindowHandle}

关键修改说明

  • 替换-Contains "DC2"为-Like "*DC2*":-Like支持通配符匹配,*表示任意长度的字符,能准确筛选出标题中包含DC2的窗口。
  • 也可使用-Match "DC2":这是正则表达式匹配,同样能实现子串匹配效果。

验证步骤

先执行以下命令确认是否正确筛选出目标进程:

Get-Process | Where-Object {$_.MainWindowTitle -like "*DC2*"} | Format-Table Id, Name, MainWindowTitle -AutoSize

若能正确显示DC2对应的进程,再执行恢复命令即可生效。


内容的提问来源于stack exchange,提问作者T-Heron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 23:00:55