如何检查程序是不是使用 .NET?

Posted

技术标签:

【中文标题】如何检查程序是不是使用 .NET?【英文标题】:How to check if a program is using .NET?如何检查程序是否使用 .NET? 【发布时间】:2011-01-06 00:10:42 【问题描述】:

我们能否检查正在运行的应用程序或程序是否使用 .Net 框架来执行自身?

【问题讨论】:

启动进程监视器,如果可执行文件以黄色突出显示,则它是托管应用程序。快点。 威尔,我想你的意思是 Process Explorer ;) 【参考方案1】:

我曾经从 Scott Hanselman 的 list of interview questions 中学到一个技巧。您可以使用以下命令轻松列出所有在命令提示符下运行 .NET 的程序:

tasklist /m "mscor*"

它将列出在其加载的模块中具有mscor* 的所有进程。

我们可以在代码中应用同样的方法:

public static bool IsDotNetProcess(this Process process)

  var modules = process.Modules.Cast<ProcessModule>().Where(
      m => m.ModuleName.StartsWith("mscor", StringComparison.InvariantCultureIgnoreCase));

  return modules.Any();

【讨论】:

请注意,这确实遗漏了可能的 Mono 进程。 @Dykam Mono 的运行时不是也叫 mscorlib.dll 吗? 运行时只是mono。或 mono.exe 在 Windows 上。 .Net 使用 PE 让操作系统使用 mscorlib.dll 来启动应用程序,但 mono 没有这样做。我认为真正的核心库称为 corlib.dll,因为它不是 MS 的 corlib。 我认为这不再适用于 .NET 4.0,DLL 已重命名。对于托管 CLR 的应用(例如 Visual Studio),您还会得到误报。 .NET 4.0 运行时称为 clr.dll。【参考方案2】:

使用 CLR COM 接口 ICorPublish 和 ICorPublishProcess。从 C# 中执行此操作的最简单方法是从 SharpDevelop 的调试器中借用一些代码,然后执行以下操作:

ICorPublish publish = new ICorPublish();
ICorPublishProcess process;

process = publish.GetProcess(PidToCheck);

if (process == null || !process.IsManaged)

    // Not managed.

else

    // Managed.

【讨论】:

我想知道,如果您从 C# 执行此操作,在什么情况下此检查会报告“未托管”? 似乎它只会考虑托管那些使用相同 CLR 的进程 - social.msdn.microsoft.com/Forums/en-US/…。所以大家一定要小心。【参考方案3】:

使用System.Reflection.Assembly.LoadFrom 函数加载.exe 文件。如果您尝试加载不是 .NET 程序集的二进制文件,此函数将引发异常。

【讨论】:

它有什么不同?正在运行的应用程序没有 .exe 文件? 那么请教他如何找到正在运行的程序对应的EXE文件;并向他展示如何处理他的进程无法读取 .EXE 文件的可能性。 是的,你是对的,我的回答不完整且不安全,很抱歉讽刺评论。 如果宿主进程是 x64 并且 exe 是 x86 的,这不起作用。【参考方案4】:

我知道这已经晚了大约一百万年,但万一它有帮助 - 我最喜欢的确定 exe 是否使用 .net 的方法是针对它运行 MSIL 反汇编程序,它带有 .net SDK。如果您确实拥有 .net exe,您将获得其内容的精美图形分解;如果是普通的老式 win32 exe,您会收到一条消息告诉您。

【讨论】:

好答案。具体来说,运行 ILDASM.EXE,它与 Visual Studio 一起自动安装。请参阅:msdn.microsoft.com/en-us/library/f7dy01k1(v=vs.110).aspx 要从 Win8/VS2013 启动 ILDASM:开始 -> Visual Studio 工具 -> VS2013 的开发人员命令提示符。从 Win8/VS2012 开始:开始 -> 开发人员命令 -> VS2012 的开发人员命令提示符。从 Win7:所有程序 -> Microsoft Visual Studio -> Visual Studio 工具 -> Visual Studio 命令提示符。【参考方案5】:

您可以使用 Win32 API(如 NtQueryInformationProcess)以编程方式获取起始图像名称,或者在 .Net 中使用 System.Diagnostics.Process.GetProcesses() 并阅读Process.StartInfo.FileName

然后使用下面 MSDN 文章中规定的详细信息打开并解码该图像的 PE 标头:

http://msdn.microsoft.com/en-us/magazine/cc301808.aspx

警告:只会检测 .NET 构建的程序集,例如不会检测到使用 CorHost API 动态托管 CLR 的 Win32 EXE。

【讨论】:

【参考方案6】:

我建议下载 Redgate 的 DotNetReflector 并检查它是否可以打开应用程序。

【讨论】:

【参考方案7】:

Performance Monitor 中提供了正在运行的 .NET 进程列表。只需运行 perfmon 并在 Monitoring Tools >> Performance Monitor 中单击 + 图标或按 Ctrl+N。在可用计数器列表中,在列表的开头找到 .NET CLR Jit 并选择一个子项。您将在 Instances of selected object 列表中看到 .NET 进程列表。

如果您想在 C# 中使用方法而不在管理员模式下运行您的应用程序,Process Hacker 工具引入了解决方案。

根据Process Hacker / .NET Tools / native.c:

大多数 .NET 进程都有一个打开名为 \BaseNamedObjects\Cor_Private_IPCBlock(v4) 的部分的句柄。 这与 ICorPublish 使用的对象相同: :GetProcess 函数。我们不调用该函数,而是简单地检查该部分对象的存在。这意味着: * 更好的性能。 * 无需管理员权限即可获取其他用户拥有的进程的 .NET 状态。

在 C#is a bit of hard work 中获取进程句柄列表。相反,您可以从 Process Hacker plugins 文件夹下载 DotNetTools.dll 并创建一个 extern 方法以使用 PhGetProcessIsDotNet 函数。

【讨论】:

以上是关于如何检查程序是不是使用 .NET?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查客户的 PC 是不是存在 .Net 相关的 DLL?

如何确定.net 应用程序是不是是“核心”应用程序?

如何检查扫描仪是不是已插入(C#、.NET TWAIN)

我可以使用 .net 检查电子邮件地址是不是存在吗?

检查用户是不是在 ASP.NET Core 中使用基于令牌的身份验证登录

如何使用“以管理员身份运行”要求自动检查我的 .NET 4 控制台应用程序 [重复]