处理 MainModule - 我可以避免 Win32 异常吗?

Posted

技术标签:

【中文标题】处理 MainModule - 我可以避免 Win32 异常吗?【英文标题】:Process MainModule - can I avoid Win32 exception? 【发布时间】:2021-12-04 12:05:32 【问题描述】:

我正在枚举进程以查找excel.exe 是否正在运行(例如)。 我从系统服务等获得了很多Win32Exception

Process[] pps = Process.GetProcesses();
foreach (var process in pps)

    string module = null;
    try
    
        module = process.MainModule?.FileName;
    
    catch (Win32Exception)
    
        continue;
    

使枚举运行 500 毫秒而不是 10 毫秒。

有没有办法在不触发异常的情况下判断一个进程是否有主模块?或者有什么其他方法可以找到进程exe路径?

【问题讨论】:

我不确定Process.GetProcessesByName("excel") 是否会表现更好。不调试也能得到 500 毫秒的延迟吗? 哈哈!你找到我了..我以为我做到了,我刚才又看了一遍,它是我运行的调试版本..确实它下降到 55 毫秒..不是 10 毫秒,但仍然比 WMI 好两倍。谢谢你推我:) 仅供参考 - GetProcessByName 是 40 毫秒 vs 50 毫秒,这还不错。 【参考方案1】:

当您尝试执行操作系统不允许的操作时,会发生此异常。您可以查看NativeErrorCode 属性以查看有关异常的更多详细信息。

您可以找到解决方案here 来处理该问题。

正如@steeeve 在评论中提到的,如果性能是您的唯一标准,您可以使用GetProcessByName

【讨论】:

如果没有 W32 错误,WMI 会慢 50 倍。不匹配与它无关。 Win32 是 API 的通用名称,而不是位数。本机错误是 -2147467259,即 access denied(尽管我以管理员身份运行该应用程序)。尽管如此 - 我问是否有可能避免异常 - 因为处理需要额外的 500 毫秒 .. 不检查它们是什么 - 真的不在乎.. "我在问是否可以避免异常" - 您必须直接使用相关的 Win32 API 函数,即通过 PInvoke,而不是使用 .NET包装类。包装器源代码是available online,因此您可以查看底层 API 调用的样子,然后在您自己的代码中进行相同的调用,只是使用不抛出异常的不同错误处理。 @BoppityBop 请使用GetProcessByName 然后 如果您从答案中删除提及位不匹配的内容,我可以接受。 (顺便说一句,我不认为“你不能从 32 位应用程序访问 64 位应用程序的路径”是真的。我没有将任何 dll 加载到 32 位进程中,我只是在检查仅描述进程的对象的属性不以任何方式代表它的代码,而且我的代码无论如何都以 64 位运行) @BoppityBop 完成

以上是关于处理 MainModule - 我可以避免 Win32 异常吗?的主要内容,如果未能解决你的问题,请参考以下文章

uniGUI之MainModule(12)

作为服务运行时,Process.MainModule枚举失败

挂钩前景窗口

从子模块运行 Spring Boot 应用程序

安全专家证实:Win11有了 TPM 也不太可能避免被攻击/破解

如何避免阻塞(C++、Win32)