问题
I'm currently working on a little PowerShell Script to reset a users Outlook Profile on a remote machine.
Before the necessary profile stuff can be done I want to check if Outlook is already running on the remote machine and, if it is, stop it gracefully. I don't want to kill the process so it can do its necessary clean-up and syncing.
When I connect to the machine with an Administrative User and execute the following commands:
Enter-PSSession $remoteMachine
$outlookProcess = Get-Process outlook
$outlookProcess.CloseMainWindow()
I ontly get
False
as a "return Value"
Killing the Process with:
Stop-Process $outlookProcess
works.
The Process im trying to close was not started by the Administrative user im connecting with, so at first i thougth maybe I'm not allowed to manipulate in this users context, but if I do the same thing on my local machine (Starting the process with a "normal" user and then using CloseMainWindow() with an Administrative user) it closes the Process without any problems.
So my question is how would I close this remote process gracefully?
回答1:
To gracefully close a Windows application, send the app a WM_CLOSE message. This should work as long as the user doesn't have modified state that will cause the app to pop UI asking whether changes should be saved or not. Here's an example that shows how to close a notepad app - again as long as there are no unsaved changes.
$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
来源:https://stackoverflow.com/questions/14436916/gracefully-closing-a-process-in-a-remote-session