我目前正在开发一个小型PowerShell脚本来重置远程计算机上的用户Outlook配置文件。
在完成必要的配置文件之前,我想检查Outlook是否已在远程计算机上运行,如果是,则优先停止它。我不想杀死这个过程,所以它可以进行必要的清理和同步。
当我使用管理用户连接到计算机并执行以下命令时:
Enter-PSSession $remoteMachine
$outlookProcess = Get-Process outlook
$outlookProcess.CloseMainWindow()
我得到了
False
作为“返回值”
用以下方法杀死进程:
Stop-Process $outlookProcess
作品。
我试图关闭的进程并不是由管理用户连接启动的,所以起初我可能不允许在这个用户上下文中操作,但是如果我在本地机器上做同样的事情(使用“普通”用户启动进程,然后使用具有管理用户的CloseMainWindow(),它会立即关闭进程。
所以我的问题是如何优雅地关闭这个远程进程?
答案 0 :(得分:2)
要正常关闭Windows应用程序,请向应用程序发送WM_CLOSE消息。只要用户没有修改状态会导致应用程序弹出UI询问是否应保存更改,这应该可以正常工作。这是一个示例,显示如何关闭记事本应用程序 - 只要没有未保存的更改。
$src = @'
using System;
using System.Runtime.InteropServices;
public static class Win32 {
public static uint WM_CLOSE = 0x10;
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
}
'@
Add-Type -TypeDefinition $src
$zero = [IntPtr]::Zero
$p = @(Get-Process Notepad)[0]
[Win32]::SendMessage($p.MainWindowHandle, [Win32]::WM_CLOSE, $zero, $zero) > $null