PowerShell自动备份脚本无法找到指定窗口问题求助
问题诊断
你的核心问题在于FindWindow调用依赖精确窗口标题匹配,且没考虑到这些关键点:
Get-Process可能返回多个匹配进程,导致$windowTitle变成数组而非单个有效字符串- 直接通过进程对象获取
MainWindowHandle比调用FindWindow更可靠,完全绕开标题匹配的坑 - 窗口可能处于最小化状态,直接调用
SetForegroundWindow会执行失败
修复方案
直接利用进程对象的MainWindowHandle属性获取窗口句柄,补充窗口恢复逻辑,同时确保仅获取单个目标进程:
# 加载必要的.NET程序集 Add-Type -AssemblyName System.Windows.Forms # 定义Win32 API调用 Add-Type @' using System; using System.Runtime.InteropServices; public class Win32 { [DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); } '@ # 精准定位7 Days to Die服务器进程(取第一个匹配项) $serverProcess = Get-Process | Where-Object { $_.MainWindowTitle -like '*7 Days to Die Dedicated Server Console*' } | Select-Object -First 1 if (-not $serverProcess) { Write-Host "❌ 未找到7 Days to Die服务器控制台进程" exit 1 } # 直接从进程获取窗口句柄(无需FindWindow) $hWnd = $serverProcess.MainWindowHandle if ($hWnd -ne [IntPtr]::Zero) { # 先恢复最小化的窗口(SW_RESTORE = 9) [Win32]::ShowWindow($hWnd, 9) Start-Sleep -Milliseconds 500 # 等待窗口恢复完成 # 将窗口置为前台 if ([Win32]::SetForegroundWindow($hWnd)) { Start-Sleep -Seconds 1 # 确保窗口获得焦点 # 发送saveworld命令并回车 [System.Windows.Forms.SendKeys]::SendWait("saveworld{ENTER}") Start-Sleep -Seconds 3 # 根据服务器性能调整等待时间,确保保存完成 # 发送shutdown命令并回车 [System.Windows.Forms.SendKeys]::SendWait("shutdown{ENTER}") Write-Host "✅ 已向服务器控制台发送保存和关闭命令" } else { Write-Host "⚠️ 无法将服务器窗口置为前台,请检查脚本权限" } } else { Write-Host "⚠️ 服务器进程无有效窗口句柄(可能以服务运行)" }
额外注意事项
- 权限问题:脚本必须以管理员身份运行,否则可能无法操作其他进程的窗口
- 服务运行的服务器:如果服务器是作为Windows服务运行的,不会有桌面窗口,
SendKeys完全无效,此时建议使用RCon协议发送命令(7 Days to Die原生支持RCon) - 等待时间:
Start-Sleep的时长需要根据服务器性能调整,确保saveworld执行完成后再发送shutdown
内容的提问来源于stack exchange,提问作者user31119702
相关产品推荐
相关产品推荐

