如何从WMI衍生的远程进程获取退出代码

5

我正在通过WMI(Win32_Process Create)远程执行一个进程,但无法确定如何确定进程何时完成执行。当我首次发出命令时,有一个退出代码(成功为0),但这只告诉我进程已经成功生成。

有办法知道进程何时结束吗?谢谢!

2个回答

4

遇到相同问题并编写了一个简单的VMI包装器:

var exitStatus = WmiOperations.Run("notepad.exe", wait:10);
Run的简介如下:
int Run(string command, // Required
        string commandline = null, // (default=none)
        string machine = null, // (default=local)
        string domain = null, // (default=current user domain)
        string username = null, // (default=current user login)
        string password = null, // (default=current user password)
        SecureString securePassword = null, // (default=current user password)
        double wait = double.PositiveInfinity); // (default=wait til command ends);

源代码可以从这里下载。

致敬凯撒,代码灵感来自这篇文章。简单来说:

  • 重构到静态类中
  • 增加了远程控制参数上的更多控制
  • 重新设计事件监视器以抑制不吸引人的CheckProcess测试

注意:您可能需要修改WMI安全设置,以允许指定的用户运行命令(请参阅http://msdn.microsoft.com/en-us/library/windows/desktop/aa393613%28v=vs.85%29.aspx) - CitizenInsane
2
这个能在Windows XP/2003上运行吗?从http://msdn.microsoft.com/en-us/library/windows/desktop/aa394376(v=vs.85).aspx看来,ExitCode在那些操作系统上不可用。 - MikeBaz - MSFT
1
我正在查询Win32_ProcessStopTrace中的ExitStatus属性,因此,在那些操作系统上可能不太可能存在。根据您的需求,使用psexec可能是一个合理的替代方案(实际上,这就是我最终使用的方法,以避免更改WMI安全设置)。 - CitizenInsane

0

这是一个在.NET对象顶部创建的示例,但是用Powershell编写的,很容易将其翻译成C#。

Clear-Host

# Authentication object
$ConOptions = New-Object System.Management.ConnectionOptions
$ConOptions.Username = "socite\administrateur"
$ConOptions.Password = "adm"
$ConOptions.EnablePrivileges = $true
$ConOptions.Impersonation = "Impersonate"
$ConOptions.Authentication = "Default"

$scope = New-Object System.Management.ManagementScope("\\192.168.183.220\root\cimV2", $ConOptions)

$ObjectGetOptions = New-Object System.Management.ObjectGetOptions($null, [System.TimeSpan]::MaxValue, $true)

# Equivalent to local :
# $proc = [wmiclass]"\\.\ROOT\CIMV2:Win32_Process"
$proc = New-Object System.Management.ManagementClass($scope, "\\192.168.183.220\ROOT\CIMV2:Win32_Process", $ObjectGetOptions)

# Now create the process remotly
$res = $proc.Create("cmd.exe")

# Now create an event to detect remote death
$timespan = New-Object System.TimeSpan(0, 0, 1)
$querryString = "SELECT * From WIN32_ProcessStopTrace WHERE ProcessID=$($res.ProcessID)"
$query = New-Object System.Management.WQLEventQuery ($querryString)

$watcher = New-Object System.Management.ManagementEventWatcher($scope, $query)

$b = $watcher.WaitForNextEvent()
$b

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接