【问题标题】:Set a process name in C#在 C# 中设置进程名称
【发布时间】:2013-09-13 17:14:14
【问题描述】:

我编写了一个应用程序来启动一个第三方程序,该程序从我的程序上的电视频道下载媒体流。我正在使用的程序是 rtmpdump.exe。它们像这样作为独立进程运行:

ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = path + rtmpdump;
startInfo.Arguments = rtmpdump_argument;
startInfo.WorkingDirectory = path;
startInfo.WindowStyle = ProcessWindowStyle.Minimized;
Process p = Process.Start(startInfo);

但是我想命名这些进程,所以如果我的程序崩溃或必须重新启动,那么我可以检查当前进程的名称,例如是否有一个名为“BBC World - News at 7”的进程.类似的东西可以识别哪些已经启动并且当前正在运行。可能吗?我找不到设置友好名称的方法。

【问题讨论】:

  • 您是否尝试这样做,以便进程在 Windows 中显示不同的名称作为正在运行的进程,还是您只需要在内部有一个标识符?

标签: c# process


【解决方案1】:

扩展 Alexei 所说的内容 - 您可以创建一个 Dictionary 来跟踪您创建的进程 ID/描述性名称。也许你应该把它写到一个文件中,以防你的程序崩溃——但你需要一些特殊的启动处理来处理进程退出。

在启动时,您希望读取文件,并检查当前进程以查看它们是否与您拥有的匹配,并删除任何不再存在的进程(错误的进程 ID 或 exe 名称)。您可能希望每次创建新进程并写入文件时都这样做。

【讨论】:

    【解决方案2】:

    您不能更改进程名称,但可以:

    【讨论】:

      【解决方案3】:

      这里有一些你可以使用的代码。

      public class ProcessTracker {
          public Dictionary<int, string> Processes { get; set; }
      
          public ProcessTracker() {
              Processes = new Dictionary<int, string>();
          }
      
          public void AddProcess(Process process, string name) {
              Processes.Add(process.Id, name);
          }
      
          //Check if what processes are still open after crash.
          public void UpdateProcesses() {
              List<Process> runningProcesses =
                  Process.GetProcesses().ToList();
      
              Processes = Processes
                  .Where(pair => runningProcesses
                      .Any(process => process.Id == pair.Key))
                  .ToDictionary(pair => pair.Key, pair => pair.Value);
          }
      
          //Use this to see if you have to restart a process.
          public bool HasProcess(string name) {
              return Processes.Any(pair => pair.Value != name);
          }
      
          //Write the file on crash.
          public void ReadFile(string path) {
              if (!(new FileInfo(path).Exists))
                  return;
      
              using (StreamReader reader = new StreamReader(path)) {
                  foreach (string line in  reader.ReadToEnd()
                      .Split(new[] {"\n"}, StringSplitOptions.RemoveEmptyEntries)) {
                      string[] keyPair = line.Split(',');
      
                      Processes.Add(int.Parse(keyPair[0]), keyPair[1]);
                  }
              }
          }
      
          //Read the file on startup.
          public void SaveFile(string path) {
              using (StreamWriter writer = new StreamWriter(path, false)) {
                  foreach (KeyValuePair<int, string> process in Processes) {
                      writer.WriteLine("{0},{1}",
                          process.Key, process.Value);
                  }
              }
          }
      }
      

      【讨论】:

      • 使用共享内存(内存映射文件)可能更好
      【解决方案4】:

      将进程信息写入文件(或内存映射文件)可能是可行的方法;

      但是,您也可以查看 Windows 消息传递。即向每个进程发送消息;并让他们回复他们的“内部名称”。

      基本上,您可以在该队列中收听所有内容;您首先发送命令命令其他进程报告其内部名称,然后他们将其连同自己的进程 ID 转储到消息队列中;

      MSMQ

      【讨论】:

        【解决方案5】:

        我自己也有同样的问题,因为我的解决方案创建了一个 新类 - MyProcessProcess 继承添加了一个属性 - ProcessId

        在我的情况下,我将 ProcessId 存储在与其他数据相关的数据库中。根据其他数据的状态,我决定终止该进程。

        然后,我将进程存储在 字典 中,如果需要,可以将其传递给其他可以访问以终止进程的类。

        所以当我决定终止一个进程时,我会通过 ProcessId 从字典中提取该进程,然后终止它。

        示例如下:

        public class Program
        {
            private static Dictionary<string, MyProcess> _processes;
        
            private static void Main()
            {
                // can store this to file or db
                var processId = Guid.NewGuid().ToString();
        
                var myProcess = new MyProcess
                {
                    StartInfo = { FileName = @"C:\HelloWorld.exe" },
                    ProcessId = processId
                };
        
                _processes = new Dictionary<string, MyProcess> {{processId, myProcess}};
        
                myProcess.Start();
        
                Thread.Sleep(5000);
        
                // read id from file or db or another
                var pr = _processes[processId];
        
                pr.Kill();
        
                Console.ReadKey();
            }
        }
        
        public class MyProcess : Process
        {
            public string ProcessId { get; set; }
        }
        

        【讨论】:

        • 您的评论具有误导性,我刚刚尝试过它仍然有效,请说明您认为它无效的原因或将其删除。
        • 如果我打开windows任务管理器,进程名不是根据'ProcessID'字符串设置的
        • 无法实现OP所追求的确切解决方案,因此答案中提供了替代方案。我的解决方案是另一种选择,我个人使用它。每次您的应用程序启动一个新进程时,您都会将其 id 记录在一个键值对中,该键值对可能与其他数据相关联。您可以让其他应用程序定期监控每个进程,根据它们的状态,可能会决定启动一个新进程。因此,您可以查看另一个应用程序的输出(生成进程的状态)以获取您提供的名称,而不是查看任务管理器的名称。然后采取相应的行动。希望对您有所帮助。
        • 谢谢你,我的错。我认为它也应该更新任务管理器
        猜你喜欢
        • 1970-01-01
        • 2014-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多