如何检查程序是不是使用 .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?