You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在VMware Workstation虚拟机运行时阻止Windows 10关机/注销,并中断关机流程以保留桌面交互?

如何在VMware Workstation虚拟机运行时阻止Windows 10关机/注销,并中断关机流程以保留桌面交互?

没问题,我来帮你解决这个痛点——你要的不仅是阻止关机,还要在关机发起的第一时间拦截,保留桌面交互甚至激活VMware窗口,这完全可以实现!先明确回答你的最后一个问题:Windows 10确实能完全中断已发起的关机流程,关键是要在系统进入关机界面之前拦截关机请求,而不是像组策略脚本那样晚一步触发。

下面给你两种实用的解决方案,分别适合喜欢动手写脚本和偏好现成工具的场景:

方案一:用PowerShell脚本+任务计划,自定义拦截逻辑

这种方法能精准检测VMware虚拟机状态,拦截关机并弹出提示,还能自动激活VMware窗口。

步骤1:编写拦截脚本

把下面的代码保存为BlockVMShutdown.ps1(路径可以自己选,比如C:\Scripts\BlockVMShutdown.ps1):

# 检测是否有VMware虚拟机在运行(vmware-vmx.exe是每个运行中虚拟机的核心进程)
$vmProcess = Get-Process -Name vmware-vmx -ErrorAction SilentlyContinue

if ($vmProcess) {
    # 加载Windows API来阻止关机并显示原因
    $apiSignature = @"
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool ShutdownBlockReasonCreate(IntPtr hWnd, string pwszReason);
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
"@
    $win32Lib = Add-Type -MemberDefinition $apiSignature -Name Win32Utils -Namespace ShutdownBlock -PassThru

    # 告诉系统阻止关机,并显示原因
    $win32Lib::ShutdownBlockReasonCreate([IntPtr]0, "VMware虚拟机正在运行,无法执行关机/注销")

    # 弹出提示框提醒用户
    Add-Type -AssemblyName System.Windows.Forms
    [System.Windows.Forms.MessageBox]::Show("VMware虚拟机正在运行,请先关闭虚拟机再尝试关机/注销!", "操作被阻止", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Warning)

    # 自动激活VMware Workstation窗口
    $vmwareWindow = Get-Process vmware | Select-Object -ExpandProperty MainWindowHandle
    if ($vmwareWindow -ne 0) {
        $win32Lib::SetForegroundWindow($vmwareWindow)
    }

    # 返回非0值通知系统取消关机流程
    exit 1
} else {
    # 无虚拟机运行,允许关机/注销
    exit 0
}

步骤2:配置任务计划触发脚本

  1. 打开「任务计划程序」,点击「创建任务」
  2. 常规选项卡:勾选「不管用户是否登录都要运行」,并勾选「使用最高权限运行」(拦截关机需要管理员权限)
  3. 触发器选项卡:添加两个触发器:
    • 触发器1:选择「当用户尝试注销时」
    • 触发器2:选择「当系统即将关闭时」
  4. 操作选项卡:添加操作「启动程序」,程序/脚本填powershell.exe,添加参数:
    -ExecutionPolicy Bypass -File "C:\Scripts\BlockVMShutdown.ps1"
    
    (注意替换成你实际的脚本路径)
  5. 设置选项卡:取消勾选「如果任务运行时间超过X小时就停止」,确保脚本能正常执行。

方案二:用AutoHotkey编写轻量监听脚本

如果你不想折腾任务计划,AutoHotkey是个更简单的选择——它能实时监听系统关机请求,一旦检测到VM运行就直接阻止,并激活VMware窗口。

步骤1:编写AutoHotkey脚本

把下面的代码保存为VMShutdownBlocker.ahk

#Persistent
; 监听系统关机/注销请求的消息
OnMessage(0x11, "HandleShutdownRequest")
return

HandleShutdownRequest(wParam, lParam) {
    ; 检测虚拟机核心进程是否存在
    Process, Exist, vmware-vmx.exe
    if ErrorLevel {
        ; 弹出警告提示
        MsgBox, 48, 操作被阻止, VMware虚拟机正在运行,请先关闭后再尝试关机/注销!
        ; 自动激活VMware Workstation窗口
        WinActivate, ahk_exe vmware.exe
        ; 返回0告诉系统取消关机
        return 0
    }
    ; 无虚拟机运行,允许关机
    return 1
}

步骤2:运行并设置开机自启

  1. 自行下载安装AutoHotkey工具
  2. 双击脚本运行,右下角会出现AutoHotkey图标,表示脚本在后台监听
  3. 把脚本快捷方式放到「启动」文件夹(Win+R输入shell:startup打开),就能实现开机自动运行。

关键注意事项

  • 两种方案都需要管理员权限:因为拦截系统级的关机操作需要更高权限,否则脚本会失效
  • 进程检测的准确性:vmware-vmx.exe是每个运行中虚拟机对应的进程,比只检测vmware.exe更靠谱(因为VMware主程序打开但没启动虚拟机时,vmware-vmx.exe不会运行)
  • 拦截时机:这两种方法都是在系统处理关机请求的早期阶段触发,所以不会出现桌面消失、进入关机界面的情况,完全保留当前桌面交互。

备注:内容来源于stack exchange,提问作者Erik

火山引擎 最新活动