Link to home
Start Free TrialLog in
Avatar of SteveDXL
SteveDXL

asked on

C# - Get Process Path From Management Watcher

Hi,
I know how to get the process names that start on Windows, however, I am unable to get the process paths of the names...

Here's my attempt:

       
                var mgmtWtch = new ManagementEventWatcher("Select * From Win32_ProcessStartTrace");
                mgmtWtch.EventArrived += new EventArrivedEventHandler(mgmtWtch_EventArrived);
                mgmtWtch.Start();

 private void mgmtWtch_EventArrived(object sender, EventArrivedEventArgs e)
        {
            String ProcessName = e.NewEvent.Properties["ProcessName"].Value.ToString();
            Process n = Process.GetProcessById(Convert.ToInt32(e.NewEvent.Properties["ProcessID"].Value));
            String ProcessPath = n.MainModule.FileName;
            if(!String.IsNullOrEmpty(ProcessName))
            {
                MessageBox.Show(ProcessName + "\n" + ProcessPath);
            }
        }

Open in new window


When I start a process, it returns an exception on GetProcessById() that "No process with pid #### exists", even though it does. Maybe something to do with this being a 32 bit application and I'm running x64 processes? It did work with one x86 process. Other times it will throw an exception "Access Denied" on n.MainModule.FileName...

Hoping someone knows a better way to do this.

Thanks!
Avatar of SteveDXL
SteveDXL

ASKER

Ah yes definitely seems like the issue is not being able to find 64bit processes from a 32 bit application. Compiling this app as a a 64 bit or "Any CPU" will cause a ton of other problems , because its intended to monitor a 32 bit process.

Hopeless?
Is what you are trying todo here, get running processes on the computer? Does it have to be from the Management Watcher?
ASKER CERTIFIED SOLUTION
Avatar of hintco
hintco

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Here is another way to do it, probably allowing System.Diagnostics and Bit of LINQ to help you:-
var lstPaths = Process.GetProcesses().Select(p => p.Modules[0].FileName);

foreach(var item in lstPaths)
{
 //do your magic here.               
}

Open in new window

Two things to note however:-
1. Run your app(even VS) as an administrator
2. For 64-bit processes you need to compile the app with Target as x64.
Thanks to everyone for offering their insight!

@hintco, this appears to be the best solution. Last night I came up with

const string wmiQueryString = "SELECT ProcessId, ExecutablePath, CommandLine FROM Win32_Process";
               using (var searcher = new ManagementObjectSearcher(wmiQueryString))
               using (var results = searcher.Get())
               {
                   var query = from p in Process.GetProcesses()
                               join mo in results.Cast<ManagementObject>()
                                   on (int)(uint)e.NewEvent.Properties["ProcessID"].Value equals (int)(uint)mo["ProcessId"]
                               select new
                                          {
                                              Process = p,
                                              Path = (string) mo["ExecutablePath"],
                                              CommandLine = (string) mo["CommandLine"],
                                          };
                   foreach (var item in query)
                   {
                       //stuff
                       break;
                   }

Open in new window


but your code seems to be much cleaner and less taxing.

Thanks again to all!
Perfect