C# 启动进程后获取该进程的友好名称

C# 启动进程后获取该进程的友好名称,c#,.net,process,C#,.net,Process,我正在为一个嵌入式系统编写一个看门狗服务,它监视一些专有进程,并在必要时重新启动它们。在你问之前,与恶意软件无关。这只是一项业务要求 我需要从我刚刚创建的进程中检索友好名称,以便稍后我可以使用该名称检索该进程,以便监视其运行状况 我的问题如下: 如果我尝试在Process.Start之后读取Process.ProcessName,我会得到一个InvalidOperationException,因为它表明进程尚未完全创建 如果我使用Process.WaitForInputIdle,也会发生同样的情

我正在为一个嵌入式系统编写一个看门狗服务,它监视一些专有进程,并在必要时重新启动它们。在你问之前,与恶意软件无关。这只是一项业务要求

我需要从我刚刚创建的进程中检索友好名称,以便稍后我可以使用该名称检索该进程,以便监视其运行状况

我的问题如下:

如果我尝试在Process.Start之后读取Process.ProcessName,我会得到一个InvalidOperationException,因为它表明进程尚未完全创建

如果我使用Process.WaitForInputIdle,也会发生同样的情况,但由于这需要一个消息泵,并且许多可执行文件可能是实际应用程序的无UI启动器,因此这可能不是一个选项

我需要在创建流程之后立即获得友好名称,然后再执行其他操作

下面是一段代码片段:

var startInfo = new ProcessStartInfo { FileName = "notepad.exe" };
var process = new Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForInputIdle();
var friendlyName = process.ProcessName;
例如,如果正在启动的进程是Firefox,这将在最后一行抛出InvalidOperationException

那我该怎么做呢?有更安全的方法吗

编辑:添加了一个代码片段以进行说明。
EDIT2:重新表述整个问题以进行澄清,遗漏了不相关的内容。

您的代码中缺少一些关键内容,请使用NotePad.exe尝试类似的操作,您将看到我所说的内容

var startInfo = new ProcessStartInfo { FileName = "notepad.exe" };
var process = new Process();
process.StartInfo = startInfo;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = false;
process.Start();
process.WaitForInputIdle();
// this line below will always be false because `process.ProcessName will be 
//notepad and process.StartInfo.FileName = notepade.exe 
if (process.ProcessName.Equals(process.StartInfo.FileName) == false)
{
   var theConfiguredProcessName = process.ProcessName;
}
另一种选择是,你可以做下面两件事中的任何一件

Process[] processName = Process.GetProcessesByName("blah.exe");
或者检查所有正在运行的进程并检查您正在运行的进程

Process[] processlist = Process.GetProcesses();
foreach(Process process in processlist)
{
   Console.WriteLine("Process: {0} ID: {1}", process.ProcessName, process.Id);
}

您的代码中缺少一些关键内容,请使用NotePad.exe尝试类似的操作,您将看到我所说的内容

var startInfo = new ProcessStartInfo { FileName = "notepad.exe" };
var process = new Process();
process.StartInfo = startInfo;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = false;
process.Start();
process.WaitForInputIdle();
// this line below will always be false because `process.ProcessName will be 
//notepad and process.StartInfo.FileName = notepade.exe 
if (process.ProcessName.Equals(process.StartInfo.FileName) == false)
{
   var theConfiguredProcessName = process.ProcessName;
}
另一种选择是,你可以做下面两件事中的任何一件

Process[] processName = Process.GetProcessesByName("blah.exe");
或者检查所有正在运行的进程并检查您正在运行的进程

Process[] processlist = Process.GetProcesses();
foreach(Process process in processlist)
{
   Console.WriteLine("Process: {0} ID: {1}", process.ProcessName, process.Id);
}

好的,经过大量的研究,我不得不求助于一个有点粗糙的解决方案

根据文档,进程名是进程的友好名称,例如Outlook,它不包括.exe扩展名或路径

考虑到这一点,我使用以下代码解决了这个问题:

var startInfo = new ProcessStartInfo { FileName = "notepad.exe" };
var process = new Process();
process.StartInfo = startInfo;
process.Start();
var friendlyName = Path.GetFileNameWithoutExtension(startInfo.FileName);
正如我所说,它仍然感觉有点不舒服,但至少它完成了工作,让我可以继续前进


无论如何,谢谢你的评论

好的,所以经过大量研究,我不得不求助于一个有点老套的解决方案

根据文档,进程名是进程的友好名称,例如Outlook,它不包括.exe扩展名或路径

考虑到这一点,我使用以下代码解决了这个问题:

var startInfo = new ProcessStartInfo { FileName = "notepad.exe" };
var process = new Process();
process.StartInfo = startInfo;
process.Start();
var friendlyName = Path.GetFileNameWithoutExtension(startInfo.FileName);
正如我所说,它仍然感觉有点不舒服,但至少它完成了工作,让我可以继续前进


无论如何,谢谢你的评论

被监控的过程是否启动了消息泵?否则,WaitForinPutile将什么也不做。也许您可以使用Process.MainModule来查找可执行文件的名称?想想看,是的。但在我的测试用例中,进程是Firefox。你是说process.MainModule.ModuleName吗?它是否总是返回与Process.ProcessName相同的值?如何显示您正在使用的代码。。这样就不会有误解了。@Axelmagani:我不能肯定地回答这个问题。但是,可执行文件的名称还不够好吗?被监视的进程是否启动了消息泵?否则,WaitForinPutile将什么也不做。也许您可以使用Process.MainModule来查找可执行文件的名称?想想看,是的。但在我的测试用例中,进程是Firefox。你是说process.MainModule.ModuleName吗?它是否总是返回与Process.ProcessName相同的值?如何显示您正在使用的代码。。这样就不会有误解了。@Axelmagani:我不能肯定地回答这个问题。但可执行文件的名称还不够好吗?我理解你的意思,但我认为不是这样。实际上,甚至没有执行比较,因为仅仅访问process.ProcessName会引发异常,因为它还不可用。此外,问题的目标是验证该值。因此,我启动进程,如果它与实际的进程名不匹配,我会更正它。。同样,如果它确实得到了值。。然后您需要附加文件扩展名,也许我访问process.ProcessName,它在这一端工作。。我建议在startInfo=newprocessstartinfo行中设置断点,然后在查看startInfo时查看FileName的值,然后通过代码逐步查看startInfo。正如我所说,该值与此无关,因为我正在尝试验证和更正它。我想你可能误解了这个问题。我想我理解你想要Axel,我现在说的是,我理解你,我不认为你不需要进行另一个条件检查就可以做到这一点,因此如果你更改名称..那么你需要动态传递{FileName}=
someVariableName}由于您在配置和process.ProcessName中没有使流程名称相同,您计划如何检查并更改它。。你需要杀死当前进程,然后生成一个新进程不,你还是误解了我。基本上,我的问题是:我需要知道我刚刚创建的进程的友好名称,以便以后可以通过名称来监视它。其余的都无关紧要。我无法使用该代码执行此操作,因为在此阶段访问Process.ProcessName会引发异常—进程尚未完全创建。这是我的问题。而不是任何其他变量的值。无论如何,我不认为WaitForInputle方法会起作用,因为一些.exe可能只是实际程序的无UI启动程序。我理解你的意思,但我认为不是这样。实际上,甚至没有执行比较,因为仅仅访问process.ProcessName会引发异常,因为它还不可用。此外,问题的目标是验证该值。因此,我启动进程,如果它与实际的进程名不匹配,我会更正它。。同样,如果它确实得到了值。。然后您需要附加文件扩展名,也许我访问process.ProcessName,它在这一端工作。。我建议在startInfo=newprocessstartinfo行中设置断点,然后在查看startInfo时查看FileName的值,然后通过代码逐步查看startInfo。正如我所说,该值与此无关,因为我正在尝试验证和更正它。我想你可能误解了这个问题。我想我理解你想要Axel的意思,现在我理解你的意思是,我不认为你不需要进行另一个条件检查就可以做到这一点,因此如果你更改名称..那么你需要动态地传递{FileName=someVariableName}既然您在config和process.ProcessName中没有使流程名称相同,那么您计划如何检查并更改它。。你需要杀死当前进程,然后生成一个新进程不,你还是误解了我。基本上,我的问题是:我需要知道我刚刚创建的进程的友好名称,以便以后可以通过名称来监视它。其余的都无关紧要。我无法使用该代码执行此操作,因为在此阶段访问Process.ProcessName会引发异常—进程尚未完全创建。这是我的问题。而不是任何其他变量的值。无论如何,我认为WaitForInputle方法不会起作用,因为一些.exe可能只是实际程序的无UI启动器。