7

I have three remote PC's to which I remotely connect. I am trying to write a simple Windows application that would display in a single window whether a particular process is running on either of the machines, e.g.

Server1: Chrome not running

Server2: Chrome IS running

Server3: Chrome IS running

I used WMI and C#. So far I've got this much:

            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!! :'(                        
                }
            }

I think it is all set up correctly, but if I MessageBox.Show(process.ToString()) inside the foreach loop, I get a whole bunch of message boxes with the following text:

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

I am kind of stuck. Is there any way I can "translate" that XXX to a process name? Or else, how can actually get the names of the processes so I can use an if statement to check whether it is a "chrome" process?

Or...is my implementation an overkill? Is there an easier way to accomplish this?

Thanks a lot!

Krzysiek
  • 1,487
  • 4
  • 19
  • 28

3 Answers3

7

In your foreach, try this:

Console.WriteLine(process["Name"]);
  • 1
    Where can I find some sort of a list of properties like "Name"? It works, just not sure where you got it from.. – Krzysiek Jun 01 '12 at 16:58
  • Good question - there has to be a list somewhere. IIRC, I originally got this from an example on CodeProject.com. – 500 - Internal Server Error Jun 01 '12 at 17:00
  • 3
    The properties oh the Win32_Process WMI class are listed in the MSDN documentation http://msdn.microsoft.com/en-us/library/windows/desktop/aa394372%28v=vs.85%29.aspx – RRUZ Jun 01 '12 at 17:05
  • @RRUZ, I was on that website earlier! I just never scrolled all the way down :( Thanks! Bookmarked! :) – Krzysiek Jun 01 '12 at 17:06
  • Also you can use a tool like the [wmi-delphi-code-creator](http://code.google.com/p/wmi-delphi-code-creator/) to inspect the WMI classes and generate the code. – RRUZ Jun 01 '12 at 17:06
3

You can filter the name of the process to watch in the WQL sentence, so you can write something like this

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

Try this sample app

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();
        }
    }
}
RRUZ
  • 134,889
  • 20
  • 356
  • 483
2

Try Process.GetProcesses("chrome", "computerName");

Defined in System.Diagnostics.Process as

public static Process[] GetProcessesByName(
   string processName,
   string machineName)
agent-j
  • 27,335
  • 5
  • 52
  • 79
  • It'll probably be a newbie question, but how do I specify the computerName of a remote machine? That is, where to specify IP, username, password...? – Krzysiek Jun 01 '12 at 16:44
  • you don't know the name of the machine you want to connect to? You'll need to know the name and/or IP address. You'll also need to be able to log in from the monitoring computer to the monitored computer as an administrator. – agent-j Jun 01 '12 at 16:49
  • 2
    I can't just say ("chrome","ipnumber").. where do I provide the username/password? – Krzysiek Jun 01 '12 at 16:50
  • +1 as it is easiest code to write/read especially if account you run it under already have permissions. You will need to impersonate another account before calling this method if current one does not have permissions (or if hitting "NTLM one hop" issue for server side code). – Alexei Levenkov Jun 01 '12 at 17:01