如何在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:选择「当系统即将关闭时」
- 操作选项卡:添加操作「启动程序」,程序/脚本填
powershell.exe,添加参数:
(注意替换成你实际的脚本路径)-ExecutionPolicy Bypass -File "C:\Scripts\BlockVMShutdown.ps1" - 设置选项卡:取消勾选「如果任务运行时间超过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:运行并设置开机自启
- 自行下载安装AutoHotkey工具
- 双击脚本运行,右下角会出现AutoHotkey图标,表示脚本在后台监听
- 把脚本快捷方式放到「启动」文件夹(Win+R输入
shell:startup打开),就能实现开机自动运行。
关键注意事项
- 两种方案都需要管理员权限:因为拦截系统级的关机操作需要更高权限,否则脚本会失效
- 进程检测的准确性:
vmware-vmx.exe是每个运行中虚拟机对应的进程,比只检测vmware.exe更靠谱(因为VMware主程序打开但没启动虚拟机时,vmware-vmx.exe不会运行) - 拦截时机:这两种方法都是在系统处理关机请求的早期阶段触发,所以不会出现桌面消失、进入关机界面的情况,完全保留当前桌面交互。
备注:内容来源于stack exchange,提问作者Erik




