【问题标题】:Check if a process is running on a remote system using C#使用 C# 检查进程是否在远程系统上运行
【发布时间】:2010-10-26 07:26:49
【问题描述】:

我正在尝试检查一个进程是否正在远程系统上运行。我正在使用以下代码:

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

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

但是,当我尝试运行代码时,出现以下错误:“无法连接到远程计算机。”

我可以使用以下命令运行 pslist: C:>pslist \remoteSystemName 所以我知道有可能得到我需要的信息,但我需要在代码中。

另一种可能是将 pslist 集成到 C# 中并搜索列表以查看该进程是否存在,但我没有找到有关如何执行此操作的信息。

【问题讨论】:

    标签: c# .net system.diagnostics


    【解决方案1】:

    您可以尝试模仿有权访问远程服务器的用户。

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

    模拟后,您将不再遇到错误。 此外,您必须确保域之间存在信任,否则模拟将不起作用。

    LogonUser works only for my domain

    【讨论】:

      【解决方案2】:

      杀死远程进程
      我发现设置了Process.MachineName后Process.Kill()方法不起作用,所以这里有一个远程杀死进程的解决方案,希望对其他人有所帮助。


      创建方法的扩展方法: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();
          }
      }
      

      当然还有查找进程和使用 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);
                  });
          }
      

      【讨论】:

        【解决方案3】:

        System.ServiceProcess.ServiceController 类用于服务。您可以使用Status 来检查它是否正在运行,并使用Stop()Start() 来控制它。

        ServiceController sc = new ServiceController();
        sc.MachineName = remoteSystem;
        sc.ServiceName = procSearc;
        
        if (sc.Status.Equals(ServiceControllerStatus.Running))
        {
           sc.Stop();
        }
        else
        {
           sc.Start();
        }
        

        【讨论】:

        • 这是我使用的完全相同的代码。我在尝试连接到 Windows 2008 Server 时遇到了“拒绝访问”消息。
        • 当我运行上述代码时,我收到一条消息,指出:无法在计算机 ComputerName 上打开记事本服务。我正在尝试检查流程,这似乎是在检查服务。两者都可以吗?
        • 我没想到这不是一项服务......我现在不确定我是否给了你一个好的答案。
        • 我刚刚在远程机器上使用 notpad 测试了我的代码,并得到了与您相同的消息。我运行你的代码没有错误。你是如何运行你的代码的?您是否有权访问远程计算机。我知道我是我测试过的远程机器上的本地管理员。
        • 这是针对服务的,不是针对进程的。我还收到错误“无法在计算机上打开 xxxx 服务”。下面的答案应该是公认的。
        【解决方案4】:

        我认为在单独运行应用程序时会出现一个异常窗口,因为我的代码中没有处理异常...

        我在堆栈跟踪中看到了原因:访问被拒绝。原因是运行调用 .NET 方法以获取进程列表的程序的用户不属于远程计算机的“性能监视器用户”组。

        之后我收到另一个异常,说远程计算机上没有运行性能监控服务。所以我在远程计算机上启动了相应的服务,瞧,它工作了!

        这是使用 Windows 7 客户端尝试获取 Windows 2008 Server 的进程列表。

        【讨论】:

          【解决方案5】:

          内部异常是否显示“拒绝访问”?

          类似的问题可能会有所帮助,它提到需要加入 Performance Monitor Users 组。

          GetProcessesByName() and Windows Server 2003 scheduled task

          【讨论】:

            【解决方案6】:

            以下是我为使其正常工作所做的工作:

            首先我添加了对 System.ServiceProcess 的引用并添加了: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);
               }
            

            【讨论】:

              最近更新 更多