在 C# 中设置进程名称

本文关键字:进程名 设置 | 更新日期: 2023-09-27 18:31:24

我编写了一个应用程序,该应用程序启动了一个第三方程序,该程序从我的程序上的电视频道下载媒体流。我正在使用的程序是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"的进程。类似的东西来识别哪个已经启动并且当前正在运行。可能吗?我找不到设置友好名称的方法。

在 C# 中设置进程名称

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

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

您无法更改进程名称,但可以:

  • 使用 Process.Id 标识进程 (标识:"...系统生成的流程唯一标识符...")
  • 获取进程命令行,看看是否有任何有趣的东西(可能需要一些 PInvoke/WMI - 如何在 C# 中读取另一个进程的命令行参数?

下面是一些您可以使用的代码。

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);
            }
        }
    }
}

进程信息写入文件(或内存映射文件)可能是要走的路;

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

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

请参阅 MSMQ

我对自己有同样的问题,因为我的解决方案创建了一个新类 - MyProcess继承Process添加了一个属性 - 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; }
}