读书人

C#如何获取硬件的温度?还有主板芯片组

发布时间: 2013-03-27 11:22:42 作者: rapoo

C#怎么获取硬件的温度?还有主板芯片组的信息.

如题, 别告诉我用WMI, WMI我已经全部看过了, 除了能获取CPU的温度(不准确)

其他的都获取不到. 这个例子已经实现了WMI的所有信息 http://download.csdn.net/source/1561647


而且WMI也获取不到主板芯片组的信息, 比如说BIOS-ID 南北桥芯片组的厂商,牌子等...这些用WMI都获取不到.



所以求高人 ,要分好说, 给出满意答案, 要多少分给多少分..
[解决办法]
我的第一反应是通过注册表来拿。

主板BIOS:[HKEY_LOCAL_MACHINE\HARDWARE\Description\System]
中央处理器CPU:[HKEY_LOCAL_MACHINE\HARDWARE\Description\System\CentralProcessor\0]

其余你要什么信息就自己从注册表找吧
[解决办法]

这里是一个范例,或许对你有所帮助(附源码)http://dl3.9hao.com/20060619/_2/winsys/othersys/WMI%B5%C4%D2%BB%B8%F6%CA%B5%CF%D6.htm 
以下是相关资料
http://baike.baidu.com/view/442461.htm
http://www.newasp.net/tech/net/8540.html
http://www.ahaoz.com/Article/203/205/545/2005/20051120102957.html

解析RTCS.VBS主要代码
该脚本可以直接访问目标的WMI,不依赖于目标的ipc$,实现远程开启/关闭目标telnet服务,为了方便大家学习我抽出了最主要的代码,具体分析如下:
set objlocator=createobject("wbemscripting.swbemlocator")
//创建WbemScripting.SwbemLocator对象(脚本接口)。
//可以看出WMI其实就是把Com组件WbemScripting.SWbemLocator封装起来罢了。
set objswbemservices=objlocator.connectserver(ipaddress,"root/default",username,password)
//通过ConnectServer函数请求连接到WMI控件服务上,root/default为命名空间。
set objinstance=objswbemservices.get("stdregprov")
//建立访问注册表的实例。
set objmethod=objinstance.methods_("SetDWORDvalue")
//建立可以更改注册表键值的方法。
set objinparam=objmethod.inparameters.spawninstance_()
//MethodData.InParameters用于获取或设置方法的输入参数。这里用spawninstance方法为它建立一个子实例,下面就可以将参数值赋予这个对象的属性。
objinparam.hdefkey=&h80000002
//hdefkey表示根键,根键的十六制值如下:
//HKEY_CLASSES_ROOT (&H80000000)
//HKEY_CURRENT_USER (&H80000001)
//HKEY_LOCAL_MACHINE (&H80000002)
//HKEY_USERS (&H80000003)
//HKEY_CURRENT_CONFIG (&H80000005)
objinparam.ssubkeyname="SOFTWARE\Microsoft\TelnetServer\1.0"
//ssubkeyname表示子键。
objinparam.svaluename="NTLM"
//svaluename表示属性名。
objinparam.uvalue=ntlm
//uvalue表示键值。
set objoutparam=objinstance.execmethod_("SetDWORDvalue",objinparam)
//利用execmethod执行方法,这里才真正改写了注册表。

//下面是修改telnet服务的TelnetPort值,原理同上。
objinparam.svaluename="TelnetPort"
objinparam.uvalue=port
set objoutparam=objinstance.execmethod_("SetDWORDvalue",objinparam)

修改telnet的注册表部分就完成了,将NTLM和TelnetPort进行了修改,要是对方的telnet服务没有开启呢?下面就需要根据telnet的具体情况,来启动telnet服务,继续看代码。

//首先查询远程主机上tlntsvr的启动方式。
set objswbemservices=objlocator.connectserver(ipaddress,"root\cimv2",username,password)
//win32_service类在root\cimv2命名空间中,作用没忘记吧?快看基础知识呵。
set colinstances=objswbemservices.execquery("select * from win32_service where name='tlntsvr'")
//注意:查询都是通过枚举来实现的。
for each objinstance in colinstances
if objinstance.startmode="Disabled" then
set objmethod=objinstance.methods_("changestartmode")
//创建changestartmode方法来改变tlntsvr的启动方式。
set objinparam=objmethod.inparameters.spawninstance_()
objinparam.startmode="Manual"
//将启动方式改为手动方式。
set objoutparam=objinstance.execmethod_("changestartmode",objinparam)
end if

//下面启动我们的telnet服务。这里zzzEVAzzz的思路好象有点不对,也不知道是不是他的疏忽,我个人认为当telnet服务已经启动时不应该用stopservice方法停止服务。


if objinstance.started=true then
intstatus=objinstance.stopservice()
//stopservice是WMI中用于停止服务实例的服务的方法。
else
intstatus=objinstance.startservice()
end if
next

手把手教你编写WMI版本的ROTS.vbs来开启3389
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\netcache]
"Enabled"="0"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]
"ShutdownWithoutLogon"="0"
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer]
"EnableAdminTSRemote"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server]
"TSEnabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TermDD]
"Start"=dword:00000002
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TermService]
"Start"=dword:00000002
[HKEY_USERS\.DEFAULT\Keyboard Layout\Toggle]
"Hotkey"="1"

原理知道了就没什么难的了,先理清我们的思路,我们的主要任务是更改注册表里的键值。首先是创建WMI对象,然后是连接到远程WMI服务器,最后修改注册表键值。
部分主要代码如下(完整的代码和详细的注释请看附带的软件包)

on error resume next
//防止出现意外。
set outstreem=wscript.stdout
if (lcase(right(wscript.fullname,11))="wscript.exe") then
set objShell=wscript.createObject("wscript.shell")
objShell.Run("cmd.exe /k cscript //nologo "&chr(34)&wscript.scriptfullname&chr(34))
//cmd后带/K参数表示执行字符串指定的命令。
wscript.quit
end if
//进行简单的检查。
if wscript.arguments.count<3 then
usage()
wscript.echo "Not enough parameters."
wscript.quit
end if
//取出参数,分别赋予几个变量。
ipaddress=wscript.arguments(0)
username=wscript.arguments(1)
password=wscript.arguments(2)
option=wscript.arguments(3)
usage()


[解决办法]
下面是核心代码,也是实现远程修改注册表的功能,我这里给出另外一种实现的方式,对照前面的代码很容易理解,我就只作简单的解释了。详细情况可以参阅MSDN文档中关于StdRegProv类的说明。 
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/stdregprov.asp)

const HKEY_LOCAL_MACHINE = &H80000002
const HKEY_USERS=&H80000003
strComputer = ipaddress

//获取wmi对象
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &_
strComputer & "\root\default:StdRegProv")

strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\netcache"
strValueName = "Enabled"
strValue=0
oReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue

strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
strValueName = "ShutdownWithoutLogon"
strValue=0
oReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue

strKeyPath = "SOFTWARE\Policies\Microsoft\Windows\Installer"
strValueName = "EnableAdminTSRemote"
strValue=1
oReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue

strKeyPath = "SYSTEM\CurrentControlSet\Control\Terminal Server"
strValueName = "TSEnabled"
strValue=1
oReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue

strKeyPath = "SYSTEM\CurrentControlSet\Services\TermDD"
strValueName = "Start"


strValue=2
oReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue

strKeyPath = "SYSTEM\CurrentControlSet\Services\TermService"
strValueName = "Start"
strValue=2
oReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue

strKeyPath = ".DEFAULT\Keyboard Layout\Toggle"
strValueName = "Hotkey"
strValue=1
oReg.SetDWORDValue HKEY_USERS,strKeyPath,strValueName,strValue

//下面实现重启远程机器
if option="/r" then
outstreem.write "Now, rebooting target...."
strwmiquery="select * from win32_operatingsystem where primary='true'"
set colinstances=objswbemservices.execquery(strwmiquery)
for each objinstance in colinstances
objinstance.win32shutdown(2)
end if
outstreem.write "Ok, rebooted the target."

//简单的用法说明的函数。
function usage()
wscript.echo string(60,"=")
wscript.echo "Wmi3389 v1.0.0"
wscript.echo "No ipc Open 3389, code written by pye."
wscript.echo "Welcome to visite www.coon.cn or Mail to grandh4408@yahoo.com.cn"
wscript.echo "Usage:"
wscript.echo "cscript "&wscript.scriptfullname&" targetIP username password [/r]"
wscript.echo "/r reboot the target this is optional"
wscript.echo "It use WMI to Open 3389 of target server."
wscript.echo string(60,"=")&vbcrlf
end function
将上面的代码复制带记事本里,保存为Wmi3389.vbs。然后在CMD里执行:
cscript Wmi3389.vbs ipaddress administrator password [/r]
看看是不是和ROTS.vbs有一样的效果啊?大家赶快实践实践吧。

四:最后的唠叨
=====================================================================================
大家可以看出WMI的功能是很强大的,这里要感谢MicroSoft了,它是永远都不会让我们失望的。WMI对象允许通过VB,VBA,WSH, VBScript, JScript,ASP,或是支持自动对象的其它环境,对WMI进行完全访问。在参考查询体系中加入 WMI Scripting V1.1 Library ,则Visual Basic或是VBA方案就可以访问这些对象了。支持ActiveX程序的操作平台可以通过对象类的代号,或是类的名称创建这些对象,这些对象的前缀是WbemScripting,如 WbemScripting.SwbemLocator。所以大家有兴趣的完全可以利用VB,WSH,VBScript, JScript,ASP等编写更多的利用WMI的黑客程序。


----------------------------------------------------
最后给你附上一段程序
/* **********************************************
* Rainsoft Development Library for Microsoft.NET
*
* Copyright (c) 2004,2005 RainTrail Studio.China
* All Rigths Reserved!
* Author: Q.yuhen (qyuhen@hotmail.com)
********************************************** */
using System;
using System.Management;
using System.Collections;
using System.Collections.Specialized;
using System.Text;

namespace Rainsoft.Management
{
#region WMIPath
public enum WMIPath
{
// 硬件
Win32_Processor, // CPU 处理器
Win32_PhysicalMemory, // 物理内存条
Win32_Keyboard, // 键盘
Win32_PointingDevice, // 点输入设备,包括鼠标。
Win32_FloppyDrive, // 软盘驱动器
Win32_DiskDrive, // 硬盘驱动器
Win32_CDROMDrive, // 光盘驱动器
Win32_BaseBoard, // 主板
Win32_BIOS, // BIOS 芯片
Win32_ParallelPort, // 并口


Win32_SerialPort, // 串口
Win32_SerialPortConfiguration, // 串口配置
Win32_SoundDevice, // 多媒体设置,一般指声卡。
Win32_SystemSlot, // 主板插槽 (ISA & PCI & AGP)
Win32_USBController, // USB 控制器
Win32_NetworkAdapter, // 网络适配器
Win32_NetworkAdapterConfiguration, // 网络适配器设置
Win32_Printer, // 打印机
Win32_PrinterConfiguration, // 打印机设置
Win32_PrintJob, // 打印机任务
Win32_TCPIPPrinterPort, // 打印机端口
Win32_POTSModem, // MODEM
Win32_POTSModemToSerialPort, // MODEM 端口
Win32_DesktopMonitor, // 显示器
Win32_DisplayConfiguration, // 显卡
Win32_DisplayControllerConfiguration, // 显卡设置
Win32_VideoController, // 显卡细节。
Win32_VideoSettings, // 显卡支持的显示模式。

// 操作系统
Win32_TimeZone, // 时区
Win32_SystemDriver, // 驱动程序
Win32_DiskPartition, // 磁盘分区
Win32_LogicalDisk, // 逻辑磁盘
Win32_LogicalDiskToPartition, // 逻辑磁盘所在分区及始末位置。
Win32_LogicalMemoryConfiguration, // 逻辑内存配置
Win32_PageFile, // 系统页文件信息
Win32_PageFileSetting, // 页文件设置
Win32_BootConfiguration, // 系统启动配置
Win32_ComputerSystem, // 计算机信息简要
Win32_OperatingSystem, // 操作系统信息
Win32_StartupCommand, // 系统自动启动程序
Win32_Service, // 系统安装的服务
Win32_Group, // 系统管理组
Win32_GroupUser, // 系统组帐号
Win32_UserAccount, // 用户帐号
Win32_Process, // 系统进程
Win32_Thread, // 系统线程
Win32_Share, // 共享
Win32_NetworkClient, // 已安装的网络客户端
Win32_NetworkProtocol, // 已安装的网络协议
}
#endregion

/// <summary>
/// 获取系统信息
/// </summary>
/// <example>
/// <code>
/// WMI w = new WMI(WMIPath.Win32_NetworkAdapterConfiguration);
/// for (int i = 0; i < w.Count; i ++)
/// {
/// if ((bool)w[i, "IPEnabled"])
/// {
/// Console.WriteLine("Caption:{0}", w[i, "Caption"]);
/// Console.WriteLine("MAC Address:{0}", w[i, "MACAddress"]);
/// }
/// }
/// </code>
/// </example>
public sealed class WMI
{
private ArrayList mocs;
private StringDictionary names; // 用来存储属性名,便于忽略大小写查询正确名称。

/// <summary>
/// 信息集合数量
/// </summary>
public int Count
{
get { return mocs.Count; }
}

/// <summary>
/// 获取指定属性值,注意某些结果可能是数组。
/// </summary>
public object this[int index, string propertyName]
{
get
{
try
{
string trueName = names[propertyName.Trim()]; // 以此可不区分大小写获得正确的属性名称。
Hashtable h = (Hashtable)mocs[index];
return h[trueName];
}
catch
{
return null;
}
}
}

/// <summary>
/// 返回所有属性名称。


/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public string[] PropertyNames(int index)
{
try
{
Hashtable h = (Hashtable)mocs[index];
string[] result = new string[h.Keys.Count];

h.Keys.CopyTo(result, 0);

Array.Sort(result);
return result;
}
catch
{
return null;
}
}

/// <summary>
/// 返回测试信息。
/// </summary>
/// <returns></returns>
public string Test()
{
try
{
StringBuilder result = new StringBuilder(1000);

for (int i = 0; i < Count; i++)
{
int j = 0;
foreach(string s in PropertyNames(i))
{
result.Append(string.Format("{0}:{1}={2}\n", ++j, s, this[i, s]));

if (this[i, s] is Array)
{
Array v1 = this[i, s] as Array;
for (int x = 0; x < v1.Length; x++)
{
result.Append("\t" + v1.GetValue(x) + "\n");
}
}
}
result.Append("======WMI=======\n");
}

return result.ToString();
}
catch
{
return string.Empty;
}
}

/// <summary>
/// 构造函数
/// </summary>
/// <param name="path"></param>
public WMI(string path)
{
names = new StringDictionary();
mocs = new ArrayList();

try
{
ManagementClass cimobject = new ManagementClass(path);
ManagementObjectCollection moc = cimobject.GetInstances();

bool ok = false;
foreach(ManagementObject mo in moc)
{
Hashtable o = new Hashtable();
mocs.Add(o);

foreach (PropertyData p in mo.Properties)
{
o.Add(p.Name, p.Value);
if (!ok) names.Add(p.Name, p.Name);
}

ok = true;
mo.Dispose();
}
moc.Dispose();
}
catch(Exception e)
{
throw new Exception(e.Message);
}
}

/// <summary>
/// 构造函数
/// </summary>
/// <param name="path"></param>
public WMI(WMIPath path): this(path.ToString())
{
}
}
}


[解决办法]
http://www.codeproject.com/script/Articles/ArticleVersion.aspx?aid=17973&av=53088
不过获取温度还是有问题
[解决办法]
稍微查了一下,这个需要主板支持,stackoverflow上查到的代码,不过我的机器上不work(错误信息: not supported),楼主不妨试试:

ManagementObjectSearcher searcher = new ManagementObjectSearcher(@"root\WMI", "SELECT * FROM MSAcpi_ThermalZoneTemperature");


foreach (ManagementObject obj in searcher.Get())
{
Double temp = Convert.ToDouble(obj["CurrentTemperature"].ToString());
temp = (temp - 2732) / 10.0;
string instance = obj["InstanceName"].ToString();

}

读书人网 >C#

热点推荐