9

I am trying to check if a process is running on a remote system. I am using the following code:

string procSearc = "notepad";
string remoteSystem = "remoteSystemName";

Process[] proce = System.Diagnostics.Process.GetProcessesByName(procSearch, remoteSystem);

However, when I try to run the code, I get the following error: "Couldn't connect to remote machine."

I am able to run pslist with the following command: C:>pslist \remoteSystemName So I know it is possible to get the information I need, but I need it in the code.

Another possibility would be to integrate pslist into C# and search the list to see if the process is there, but I have not found information on how to do this.

Zifre
  • 26,504
  • 11
  • 85
  • 105

6 Answers6

8

Use the System.ServiceProcess.ServiceController class for a service. You can use Status to check if it's running and the Stop() and Start() to control it.

ServiceController sc = new ServiceController();
sc.MachineName = remoteSystem;
sc.ServiceName = procSearc;

if (sc.Status.Equals(ServiceControllerStatus.Running))
{
   sc.Stop();
}
else
{
   sc.Start();
}
Liam
  • 27,717
  • 28
  • 128
  • 190
Larry Hipp
  • 6,205
  • 3
  • 26
  • 31
  • This is the exact same code I use for this. I have run into the "Access Denied" message when trying to connect to Windows 2008 Server. – Hector Sosa Jr May 14 '09 at 20:27
  • 1
    When I run the above code, I get an message stating: Cannot open notepad service on computer ComputerName. I am trying to check the process and this seems to be checking a service. Can it do both? –  May 14 '09 at 20:40
  • I was not thinking about this not being a service... I am now not sure that I gave you a good answer. – Larry Hipp May 14 '09 at 20:48
  • I just tested my code with notpad on a remote machine and got the same message you got. I ran your code without errors. How are you running your code? Do you have access to the remote machine. I know I am a local admin on the remote machine I tested with. – Larry Hipp May 14 '09 at 20:59
  • Below is what I did, and it is working. Thanks for your help. –  May 14 '09 at 21:13
  • 1
    This is for services, not for proccesses. I also get the error "Cannot open xxxx service on computer". The answer below should be the accepted one. – Hylle May 16 '18 at 08:34
4

Below is what I did to get this to work:

First I added a reference to System.ServiceProcess and added: using System.ServiceProcess;

string remoteSystem = "remoteSystemName";
string procSearch = "notepad";            
Process[] proc = System.Diagnostics.Process.GetProcessesByName(procSearch, remoteSystem);

   if (proc.Length > 0)

   {
        Console.WriteLine("Able to find: " + proc[0]);
   }
   else
   {
        Console.WriteLine("Unable to find: " + procSearch);
   }
Jeremy McGee
  • 24,842
  • 10
  • 63
  • 95
1

Does the inner Exception say "Access Denied"?

A similar question may help, it mentions needing to be in the Performance Monitor Users group.

GetProcessesByName() and Windows Server 2003 scheduled task

Community
  • 1
  • 1
Crispy
  • 5,557
  • 3
  • 30
  • 35
0

I figured when running the application by itself I would get an exception window, because exceptions were not handled within my code...

There I saw the reason in the stacktrace: access denied. The reason was that the user running the program that was calling the .NET method to get the process list was not part of the "Performance Monitor Users" group of the remote machine.

After that I got another exception saying that the performance monitoring service was not running on the remote machine. So I started the corresponding service at the remote computer and voila it worked!

This was using a Windows 7 client trying to get the process list of a Windows 2008 Server.

Marcell
  • 809
  • 8
  • 23
0

Killing the remote process
I found that the Process.Kill() method does not work when the Process.MachineName has been set, so here is a solution for killing the process remotely, hope it helps others.


The extension method to create the method: KillRemoteProcess

public static class ProcessExtensions
{
    public static void KillRemoteProcess(this Process p, string user, string password)
    {
        new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = "TaskKill.exe",
                Arguments = string.Format("/pid {0} /s {1} /u {2} /p {3}", p.Id, p.MachineName, user, password),
                WindowStyle = ProcessWindowStyle.Hidden,
                CreateNoWindow = true
            }
        }.Start();
    }
}

And ofcourse the method to find the processes and consume the KillRemoteProcess

 public static void KillProcessesRemote()
    {
        string targetProcessName = "myProcess"; //Do not put 'process.exe' here just 'process'
        string targetMachine = "remotMachine"; //Target machine
        string username = "myUser"; //Username
        string password = "myPassword"; //Password

        Parallel.ForEach<Process>( //Kill all processes found
            source: System.Diagnostics.Process.GetProcessesByName(targetProcessName, targetMachine),
            body: process => {
                process.KillRemoteProcess(username, password);
            });
    }
Nick Prozee
  • 2,823
  • 4
  • 22
  • 49
0

You may try impersonate to the user that have access to the remote server.

https://learn.microsoft.com/en-us/dotnet/api/system.security.principal.windowsimpersonationcontext?redirectedfrom=MSDN&view=netframework-4.7.2

After Impersonation, you will no longer hit the error. Also, you have to make sure there is trust between domain, else impersonation will not work.

LogonUser works only for my domain

Xavier
  • 83
  • 6