2013-01-21 41 views
1

我目前正在研究一个小PowerShell脚本来重置远程计算机上的用户Outlook配置文件。在远程会话中优雅地关闭进程

之前必要的轮廓的东西可以做我要检查如果Outlook已经在远程机器上运行,并且,如果是,停止正常。我不想杀死这个进程,因此它可以进行必要的清理和同步。

当我连接到机器中管理用户,并执行以下命令:

Enter-PSSession $remoteMachine 
$outlookProcess = Get-Process outlook 
$outlookProcess.CloseMainWindow() 

我ontly得到

False 

作为“返回值”

中止进程搭配:

Stop-Process $outlookProcess 

的作品。

im试图关闭的进程不是由管理用户im连接启动的,所以起初我可能不允许在这个用户环境中操作,但如果我在本地计算机上执行同样的操作(使用“普通”用户启动进程,然后使用管理用户的CloseMainWindow()),它会关闭进程而不会出现任何问题。

所以我的问题是如何将我正常关闭这个偏僻的过程?

+0

在你本地测试中是否在同一个Windows Session中有两个登录? (GUI元素的范围 - 包括将关闭消息发送到一个窗口 - 被会话限制),您可以通过在Process Explorer中添加“Session”列或Task Manager中的“Session Id”来查看哪个进程在哪个进程中。 ) – Richard

+1

是的,我在切换用户后尝试过,现在我收到了相同的错误消息。那么有什么办法可以在不直接杀死它的情况下关闭进程? – johmerz

+0

答案是否定的,没有与Outlook相同的会话运行。 – Richard

回答

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 
+1

这看起来像$ myProcess.CloseMainWindow()提供的相同行为。可悲的是,只有运行这些命令的进程在同一个Windows会话中运行,这也是有效的。如果我在远程会话中尝试此操作(并且不重新输出为$ null),我只返回'0',但记事本窗口仍然保持打开状态。 (我没有做任何未保存的更改。) – johmerz