如何通过编程(C#)判断软件是在虚拟机上运行还是在物理机器上运行

如何通过编程(C#)判断软件是在虚拟机上运行还是在物理机器上运行,c#,.net,windows,virtual-machine,C#,.net,Windows,Virtual Machine,我已经研究了好几天了,研究如何通过编程进行区分(C#) 如果我的软件(Windows)在VM或物理计算机上运行。我发现的方法有两种: 测试指示您正在特定类型的VM(VMWare、AMI等)上运行的特定属性。缺点:如果你没有在上面跑步呢?如果这些属性可以由制造商轻松更改,又会怎样 尝试使用WMI通过查询某些属性来确定这一点:我看到至少五段不同的代码,它们相互矛盾,并且有人评论“它不工作” 我觉得很难相信我们没有一个明确的解决办法来作出这种区分。有人能为这个问题共享一段健壮的代码吗?据我所知,没有可

我已经研究了好几天了,研究如何通过编程进行区分(C#) 如果我的软件(Windows)在VM或物理计算机上运行。我发现的方法有两种:

  • 测试指示您正在特定类型的VM(VMWare、AMI等)上运行的特定属性。缺点:如果你没有在上面跑步呢?如果这些属性可以由制造商轻松更改,又会怎样
  • 尝试使用WMI通过查询某些属性来确定这一点:我看到至少五段不同的代码,它们相互矛盾,并且有人评论“它不工作”

  • 我觉得很难相信我们没有一个明确的解决办法来作出这种区分。有人能为这个问题共享一段健壮的代码吗?

    据我所知,没有可靠的方法来确定您是否处于虚拟环境中

    首先,我想说:

    • 查找特定于VM的虚拟硬件(例如网络适配器或USB控制器等)
    • 查找特定于VM的处理器功能 一些虚拟机引入了额外的指令集

    可能还有别的事

    我的建议是轮询运行应用程序的机器的注册表,以查找VM插入的特定键。物理机器极不可能拥有这些密钥。

    例如,下面是我的一个VMware开发框中一些键的屏幕截图。
    如果应用程序正在运行VMware,您可以从应用程序中检查是否存在部分或所有这些密钥

    由于这是用C#标记的,我建议您使用以下堆栈溢出问题中的方法:

    同样的方法也适用于任何其他虚拟机系统


    通过检查此选项,您想实现什么目标?通常,很容易判断您是否在某些类型的虚拟化上运行,但有些可能不太容易检测。Mybe检查虚拟CPU包含的信息可能会有所帮助:出于某些许可目的,我们的要求是区分平台之间的差异。我真的不太了解虚拟化的世界,但你的意思是说没有一个可查询的属性可以区分虚拟环境和物理环境?@user181218在某些情况下没有,因为这就是整个想法:确保虚拟环境尽可能真实;遇到了一些与许可相关的问题,我可以告诉您,所有可识别信息都可以被虚拟机的主机伪造。您可能还需要研究“蓝色药丸检测”,这是一种检测试图向您隐藏的虚拟机监控程序的艺术。遗憾的是,首先,这些信息很容易伪造(实际上,每个设备类型、型号和/或序列号都存储在一个明文文件中,VM在启动时读取该文件)。如果物理服务器运行多个虚拟机,而您的应用程序只是在物理服务器下运行,该怎么办?它们将安装VMWare产品的密钥。@Michael J.Gray,有趣且有效的评论。我只能代表VMWare发言,因为我使用的是VMWare,但主机和来宾上的特定密钥不同。如果有人使用它,则根据作者关于硬件欺骗的回应,该要求的另一部分是,这些密钥可能会被某些虚拟机监控程序模块或操作系统下的操作系统绕过/更改/编辑。它可以检测到ion软件试图读取一个密钥,然后返回其他密钥的结果,从而破坏了您的检测机制。我相信所有方法都很容易被阻止,因为应用程序只知道操作系统/硬件告诉它什么。当您进入虚拟硬件时,它可以表示任何内容,甚至可以添加或删除CPU指令。