【问题标题】:Is a process running on a remote machine?进程是否在远程机器上运行?
【发布时间】:2012-06-01 16:40:31
【问题描述】:

我有三台远程连接的远程 PC。我正在尝试编写一个简单的 Windows 应用程序,该应用程序将在单个窗口中显示特定进程是否在任何一台机器上运行,例如

Server1:Chrome 未运行

Server2:Chrome 正在运行

Server3:Chrome 正在运行

我使用了 WMI 和 C#。到目前为止,我有这么多:

            ConnectionOptions connectoptions = new ConnectionOptions();

            connectoptions.Username = @"domain\username";
            connectoptions.Password = "password";

            //IP Address of the remote machine
            string ipAddress = "192.168.0.217";
            ManagementScope scope = new ManagementScope(@"\\" + ipAddress + @"\root\cimv2");
            scope.Options = connectoptions;
            //Define the WMI query to be executed on the remote machine
            SelectQuery query = new SelectQuery("select * from Win32_Process");

            using (ManagementObjectSearcher searcher = new
                        ManagementObjectSearcher(scope, query))
            {

                ManagementObjectCollection collection = searcher.Get();
                foreach (ManagementObject process in collection)
                {
                    // dwarfs stole the code!! :'(                        
                }
            }

我认为这一切都设置正确,但如果我在 foreach 循环中使用 MessageBox.Show(process.ToString()),我会得到一大堆带有以下文本的消息框:

\\username\root\cimv2:W32_Process.Handle="XXX"

我有点卡住了。有什么方法可以将 XXX“翻译”为进程名称?否则,如何才能真正获取进程的名称,以便我可以使用 if 语句来检查它是否是“chrome”进程?

或者...我的实现是不是有点矫枉过正?有没有更简单的方法来做到这一点?

非常感谢!

【问题讨论】:

    标签: c# process wmi remote-connection


    【解决方案1】:

    在你的 foreach 中,试试这个:

    Console.WriteLine(process["Name"]);
    

    【讨论】:

    • 在哪里可以找到某种属性列表,例如“名称”?它有效,只是不确定你从哪里得到它..
    • 好问题 - 某处必须有一个列表。 IIRC,我最初是从 CodeProject.com 上的一个示例中得到的。
    • Win32_Process WMI 类的属性列在 MSDN 文档msdn.microsoft.com/en-us/library/windows/desktop/…
    • @RRUZ,我之前在那个网站上!我只是从来没有一直向下滚动:(谢谢!书签!:)
    • 您也可以使用wmi-delphi-code-creator 之类的工具来检查 WMI 类并生成代码。
    【解决方案2】:

    可以在WQL语句中过滤要观察的进程名,这样就可以这样写

     SelectQuery query = new SelectQuery("select * from Win32_Process Where Name='Chrome.exe'");
    

    试试这个示例应用

    using System;
    using System.Collections.Generic;
    using System.Management;
    using System.Text;
    
    namespace GetWMI_Info
    {
        class Program
        {
    
            static void Main(string[] args)
            {
                try
                {
                    string ComputerName = "localhost";
                    ManagementScope Scope;                
    
                    if (!ComputerName.Equals("localhost", StringComparison.OrdinalIgnoreCase)) 
                    {
                        ConnectionOptions Conn = new ConnectionOptions();
                        Conn.Username  = "";
                        Conn.Password  = "";
                        Conn.Authority = "ntlmdomain:DOMAIN";
                        Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), Conn);
                    }
                    else
                        Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), null);
    
                    Scope.Connect();
                    ObjectQuery Query = new ObjectQuery("SELECT * FROM Win32_Process Where Name='Chrome.exe'");
                    ManagementObjectSearcher Searcher = new ManagementObjectSearcher(Scope, Query);
    
    
                    foreach (ManagementObject WmiObject in Searcher.Get())
                    {
                      //for each instance found, do something  
                      Console.WriteLine("{0,-35} {1,-40}","Name",WmiObject["Name"]);
    
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(String.Format("Exception {0} Trace {1}",e.Message,e.StackTrace));
                }
                Console.WriteLine("Press Enter to exit");
                Console.Read();
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      试试Process.GetProcesses("chrome", "computerName")

      在 System.Diagnostics.Process 中定义为

      public static Process[] GetProcessesByName(
         string processName,
         string machineName)
      

      【讨论】:

      • 这可能是一个新手问题,但是我如何指定远程机器的计算机名?也就是在哪里指定IP、用户名、密码……?
      • 您不知道要连接的机器的名称?您需要知道名称和/或 IP 地址。您还需要能够以管理员身份从监控计算机登录到被监控计算机。
      • 我不能只说 ("chrome","ipnumber").. 我在哪里提供用户名/密码?
      • +1 因为它是最容易编写/读取的代码,尤其是在您运行它的帐户已经拥有权限的情况下。如果当前帐户没有权限(或者如果遇到服务器端代码的“NTLM one hop”问题),您将需要在调用此方法之前模拟另一个帐户。
      最近更新 更多