using Microsoft.Win32; using System; using System.Collections.Generic; using System.Management; using System.Runtime.InteropServices; using System.Text; namespace Znyc.Admin.Commons.Device { /// /// 获取系统信息、电脑CPU、磁盘、网卡、内存等相关信息辅助类 /// public sealed class HardwareInfoHelper { #region 硬盘信息获取 [DllImport("kernel32.dll")] private static extern int GetVolumeInformation( string lpRootPathName, string lpVolumeNameBuffer, int nVolumeNameSize, ref int lpVolumeSerialNumber, int lpMaximumComponentLength, int lpFileSystemFlags, string lpFileSystemNameBuffer, int nFileSystemNameSize ); /// /// 获得盘符为drvID的硬盘序列号,缺省为C /// /// 盘符,如"C" /// public static string HDVal(string drvID) { const int MAX_FILENAME_LEN = 256; int retVal = 0; int a = 0; int b = 0; string str1 = null; string str2 = null; int i = GetVolumeInformation( drvID + @":\", str1, MAX_FILENAME_LEN, ref retVal, a, b, str2, MAX_FILENAME_LEN ); return retVal.ToString(); } /// /// 获取默认C盘的磁盘序列号 /// /// public static string HDVal() { return HDVal("C"); } /// /// 获取硬盘ID /// /// public static string GetDiskID() { string HDid = ""; ManagementClass mc = new ManagementClass("Win32_DiskDrive"); ManagementObjectCollection moc = mc.GetInstances(); foreach (ManagementObject mo in moc) { HDid = mo.Properties["signature"].Value.ToString(); } return HDid; } /// /// 获取硬盘Model的信息 /// public static string GetDiskModel() { string HDid = string.Empty; using (ManagementClass mc = new ManagementClass("Win32_DiskDrive")) { ManagementObjectCollection moc = mc.GetInstances(); foreach (ManagementObject mo in moc) { HDid = (string)mo.Properties["Model"].Value; } } return HDid; } #endregion 硬盘信息获取 #region CPU信息获取 #region CpuUsage类 /// /// 定义一个抽象基类实现CPU使用率计数器 /// public abstract class CpuUsage { /// /// Creates and returns a CpuUsage instance that can be used to query the CPU time on this operating system. /// /// An instance of the CpuUsage class. /// This platform is not supported -or- initialization of the CPUUsage object failed. public static CpuUsage Create() { if (m_CpuUsage == null) { if (Environment.OSVersion.Platform == PlatformID.Win32NT) { m_CpuUsage = new CpuUsageNt(); } else if (Environment.OSVersion.Platform == PlatformID.Win32Windows) { m_CpuUsage = new CpuUsage9x(); } else { throw new NotSupportedException(); } } return m_CpuUsage; } /// /// Determines the current average CPU load. /// /// An integer that holds the CPU load percentage. /// One of the system calls fails. The CPU time can not be obtained. public abstract int Query(); /// /// Holds an instance of the CPUUsage class. /// private static CpuUsage m_CpuUsage = null; } //------------------------------------------- win 9x --------------------------------------- /// /// Inherits the CPUUsage class and implements the Query method for Windows 9x systems. /// /// ///

This class works on Windows 98 and Windows Millenium Edition.

///

You should not use this class directly in your code. Use the CPUUsage.Create() method to instantiate a CPUUsage object.

///
internal sealed class CpuUsage9x : CpuUsage { /// /// Initializes a new CPUUsage9x instance. /// /// One of the system calls fails. public CpuUsage9x() { try { // start the counter by reading the value of the 'StartStat' key RegistryKey startKey = Registry.PerformanceData.OpenSubKey(@"PerfStats\StartStat", false); if (startKey == null) { throw new NotSupportedException(); } startKey.GetValue(@"KERNEL\CPUUsage"); startKey.Close(); // open the counter's value key m_StatData = Registry.PerformanceData.OpenSubKey(@"PerfStats\StatData", false); if (m_StatData == null) { throw new NotSupportedException(); } } catch (NotSupportedException e) { throw e; } catch (Exception e) { throw new NotSupportedException("Error while querying the system information.", e); } } /// /// Determines the current average CPU load. /// /// An integer that holds the CPU load percentage. /// One of the system calls fails. The CPU time can not be obtained. public override int Query() { try { return (int)m_StatData.GetValue(@"KERNEL\CPUUsage"); } catch (Exception e) { throw new NotSupportedException("Error while querying the system information.", e); } } /// /// Closes the allocated resources. /// ~CpuUsage9x() { try { m_StatData.Close(); } catch { } // stopping the counter try { RegistryKey stopKey = Registry.PerformanceData.OpenSubKey(@"PerfStats\StopStat", false); stopKey.GetValue(@"KERNEL\CPUUsage", false); stopKey.Close(); } catch { } } /// Holds the registry key that's used to read the CPU load. private readonly RegistryKey m_StatData; } //------------------------------------------- win nt --------------------------------------- /// /// Inherits the CPUUsage class and implements the Query method for Windows NT systems. /// /// ///

This class works on Windows NT4, Windows 2000, Windows XP, Windows .NET Server and higher.

///

You should not use this class directly in your code. Use the CPUUsage.Create() method to instantiate a CPUUsage object.

///
internal sealed class CpuUsageNt : CpuUsage { /// /// Initializes a new CpuUsageNt instance. /// /// One of the system calls fails. public CpuUsageNt() { byte[] timeInfo = new byte[32]; // SYSTEM_TIME_INFORMATION structure byte[] perfInfo = new byte[312]; // SYSTEM_PERFORMANCE_INFORMATION structure byte[] baseInfo = new byte[44]; // SYSTEM_BASIC_INFORMATION structure int ret; // get new system time ret = NtQuerySystemInformation(SYSTEM_TIMEINFORMATION, timeInfo, timeInfo.Length, IntPtr.Zero); if (ret != NO_ERROR) { throw new NotSupportedException(); } // get new CPU's idle time ret = NtQuerySystemInformation(SYSTEM_PERFORMANCEINFORMATION, perfInfo, perfInfo.Length, IntPtr.Zero); if (ret != NO_ERROR) { throw new NotSupportedException(); } // get number of processors in the system ret = NtQuerySystemInformation(SYSTEM_BASICINFORMATION, baseInfo, baseInfo.Length, IntPtr.Zero); if (ret != NO_ERROR) { throw new NotSupportedException(); } // store new CPU's idle and system time and number of processors oldIdleTime = BitConverter.ToInt64(perfInfo, 0); // SYSTEM_PERFORMANCE_INFORMATION.liIdleTime oldSystemTime = BitConverter.ToInt64(timeInfo, 8); // SYSTEM_TIME_INFORMATION.liKeSystemTime processorCount = baseInfo[40]; } /// /// Determines the current average CPU load. /// /// An integer that holds the CPU load percentage. /// One of the system calls fails. The CPU time can not be obtained. public override int Query() { byte[] timeInfo = new byte[32]; // SYSTEM_TIME_INFORMATION structure byte[] perfInfo = new byte[312]; // SYSTEM_PERFORMANCE_INFORMATION structure double dbIdleTime, dbSystemTime; int ret; // get new system time ret = NtQuerySystemInformation(SYSTEM_TIMEINFORMATION, timeInfo, timeInfo.Length, IntPtr.Zero); if (ret != NO_ERROR) { throw new NotSupportedException(); } // get new CPU's idle time ret = NtQuerySystemInformation(SYSTEM_PERFORMANCEINFORMATION, perfInfo, perfInfo.Length, IntPtr.Zero); if (ret != NO_ERROR) { throw new NotSupportedException(); } // CurrentValue = NewValue - OldValue dbIdleTime = BitConverter.ToInt64(perfInfo, 0) - oldIdleTime; dbSystemTime = BitConverter.ToInt64(timeInfo, 8) - oldSystemTime; // CurrentCpuIdle = IdleTime / SystemTime if (dbSystemTime != 0) { dbIdleTime = dbIdleTime / dbSystemTime; } // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors dbIdleTime = 100.0 - dbIdleTime * 100.0 / processorCount + 0.5; // store new CPU's idle and system time oldIdleTime = BitConverter.ToInt64(perfInfo, 0); // SYSTEM_PERFORMANCE_INFORMATION.liIdleTime oldSystemTime = BitConverter.ToInt64(timeInfo, 8); // SYSTEM_TIME_INFORMATION.liKeSystemTime return (int)dbIdleTime; } /// /// NtQuerySystemInformation is an internal Windows function that retrieves various kinds of system information. /// /// One of the values enumerated in SYSTEM_INFORMATION_CLASS, indicating the kind of system information to be retrieved. /// Points to a buffer where the requested information is to be returned. The size and structure of this information varies depending on the value of the SystemInformationClass parameter. /// Length of the buffer pointed to by the SystemInformation parameter. /// Optional pointer to a location where the function writes the actual size of the information requested. /// Returns a success NTSTATUS if successful, and an NTSTATUS error code otherwise. [DllImport("ntdll", EntryPoint = "NtQuerySystemInformation")] private static extern int NtQuerySystemInformation(int dwInfoType, byte[] lpStructure, int dwSize, IntPtr returnLength); /// Returns the number of processors in the system in a SYSTEM_BASIC_INFORMATION structure. private const int SYSTEM_BASICINFORMATION = 0; /// Returns an opaque SYSTEM_PERFORMANCE_INFORMATION structure. private const int SYSTEM_PERFORMANCEINFORMATION = 2; /// Returns an opaque SYSTEM_TIMEOFDAY_INFORMATION structure. private const int SYSTEM_TIMEINFORMATION = 3; /// The value returned by NtQuerySystemInformation is no error occurred. private const int NO_ERROR = 0; /// Holds the old idle time. private long oldIdleTime; /// Holds the old system time. private long oldSystemTime; /// Holds the number of processors in the system. private readonly double processorCount; } #endregion CpuUsage类 /// /// 获得Cpu使用率 /// public static int GetCpuUsage() { return CpuUsage.Create().Query(); } /// /// 获取CPU的ID /// /// public static string GetCPUId() { string strCpuID = ""; try { ManagementClass mc = new ManagementClass("Win32_Processor"); ManagementObjectCollection moc = mc.GetInstances(); foreach (ManagementObject mo in moc) { strCpuID = mo.Properties["ProcessorId"].Value.ToString(); break; } } catch { strCpuID = "078BFBFF00020FC1"; //默认给出一个 } return strCpuID; } /// /// 获取CPU的名称 /// /// public static string GetCPUName() { RegistryKey rk = Registry.LocalMachine.OpenSubKey(@"HARDWARE\DESCRIPTION\System\CentralProcessor\0"); object obj = rk.GetValue("ProcessorNameString"); string CPUName = (string)obj; return CPUName.TrimStart(); } #endregion CPU信息获取 #region USB盘符列表 /// /// 返回USB盘符列表 /// public static List GetUSBDriveLetters() { List list = new List(); ManagementObjectSearcher ddMgmtObjSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive WHERE InterfaceType='USB'"); foreach (ManagementObject ddObj in ddMgmtObjSearcher.Get()) { foreach (ManagementObject dpObj in ddObj.GetRelated("Win32_DiskPartition")) { foreach (ManagementObject ldObj in dpObj.GetRelated("Win32_LogicalDisk")) { list.Add(ldObj["DeviceID"].ToString()); } } } return list; } #endregion USB盘符列表 #region 获取硬盘信息的实现 #region 结构 /// /// 硬盘信息 /// [Serializable] public struct HardDiskInfo { /// /// 型号 /// public string ModuleNumber; /// /// 固件版本 /// public string Firmware; /// /// 序列号 /// public string SerialNumber; /// /// 容量,以M为单位 /// public uint Capacity; } [StructLayout(LayoutKind.Sequential, Pack = 1)] internal struct GetVersionOutParams { public byte bVersion; public byte bRevision; public byte bReserved; public byte bIDEDeviceMap; public uint fCapabilities; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public uint[] dwReserved; // For future use. } [StructLayout(LayoutKind.Sequential, Pack = 1)] internal struct IdeRegs { public byte bFeaturesReg; public byte bSectorCountReg; public byte bSectorNumberReg; public byte bCylLowReg; public byte bCylHighReg; public byte bDriveHeadReg; public byte bCommandReg; public byte bReserved; } [StructLayout(LayoutKind.Sequential, Pack = 1)] internal struct SendCmdInParams { public uint cBufferSize; public IdeRegs irDriveRegs; public byte bDriveNumber; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] bReserved; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public uint[] dwReserved; public byte bBuffer; } [StructLayout(LayoutKind.Sequential, Pack = 1)] internal struct DriverStatus { public byte bDriverError; public byte bIDEStatus; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] bReserved; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public uint[] dwReserved; } [StructLayout(LayoutKind.Sequential, Pack = 1)] internal struct SendCmdOutParams { public uint cBufferSize; public DriverStatus DriverStatus; public IdSector bBuffer; } [StructLayout(LayoutKind.Sequential, Pack = 1, Size = 512)] internal struct IdSector { public ushort wGenConfig; public ushort wNumCyls; public ushort wReserved; public ushort wNumHeads; public ushort wBytesPerTrack; public ushort wBytesPerSector; public ushort wSectorsPerTrack; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public ushort[] wVendorUnique; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] sSerialNumber; public ushort wBufferType; public ushort wBufferSize; public ushort wECCSize; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] sFirmwareRev; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)] public byte[] sModelNumber; public ushort wMoreVendorUnique; public ushort wDoubleWordIO; public ushort wCapabilities; public ushort wReserved1; public ushort wPIOTiming; public ushort wDMATiming; public ushort wBS; public ushort wNumCurrentCyls; public ushort wNumCurrentHeads; public ushort wNumCurrentSectorsPerTrack; public uint ulCurrentSectorCapacity; public ushort wMultSectorStuff; public uint ulTotalAddressableSectors; public ushort wSingleWordDMA; public ushort wMultiWordDMA; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] bReserved; } #endregion 结构 #region API [DllImport("kernel32.dll", SetLastError = true)] private static extern int CloseHandle(IntPtr hObject); [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr CreateFile( string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile); [DllImport("kernel32.dll")] private static extern int DeviceIoControl( IntPtr hDevice, uint dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize, ref GetVersionOutParams lpOutBuffer, uint nOutBufferSize, ref uint lpBytesReturned, [Out] IntPtr lpOverlapped); [DllImport("kernel32.dll")] private static extern int DeviceIoControl( IntPtr hDevice, uint dwIoControlCode, ref SendCmdInParams lpInBuffer, uint nInBufferSize, ref SendCmdOutParams lpOutBuffer, uint nOutBufferSize, ref uint lpBytesReturned, [Out] IntPtr lpOverlapped); private const uint DFP_GET_VERSION = 0x00074080; private const uint DFP_SEND_DRIVE_COMMAND = 0x0007c084; private const uint DFP_RECEIVE_DRIVE_DATA = 0x0007c088; private const uint GENERIC_READ = 0x80000000; private const uint GENERIC_WRITE = 0x40000000; private const uint FILE_SHARE_READ = 0x00000001; private const uint FILE_SHARE_WRITE = 0x00000002; private const uint CREATE_NEW = 1; private const uint OPEN_EXISTING = 3; #endregion API /// /// 获取9X架构的硬盘信息 /// private static HardDiskInfo GetHddInfo9x(byte driveIndex) { GetVersionOutParams vers = new GetVersionOutParams(); SendCmdInParams inParam = new SendCmdInParams(); SendCmdOutParams outParam = new SendCmdOutParams(); uint bytesReturned = 0; IntPtr hDevice = CreateFile( @"\\.\Smartvsd", 0, 0, IntPtr.Zero, CREATE_NEW, 0, IntPtr.Zero); if (hDevice == IntPtr.Zero) { throw new Exception("Open smartvsd.vxd failed."); } if (0 == DeviceIoControl( hDevice, DFP_GET_VERSION, IntPtr.Zero, 0, ref vers, (uint)Marshal.SizeOf(vers), ref bytesReturned, IntPtr.Zero)) { CloseHandle(hDevice); throw new Exception("DeviceIoControl failed:DFP_GET_VERSION"); } // If IDE identify command not supported, fails if (0 == (vers.fCapabilities & 1)) { CloseHandle(hDevice); throw new Exception("Error: IDE identify command not supported."); } if (0 != (driveIndex & 1)) { inParam.irDriveRegs.bDriveHeadReg = 0xb0; } else { inParam.irDriveRegs.bDriveHeadReg = 0xa0; } if (0 != (vers.fCapabilities & (16 >> driveIndex))) { // We don''t detect a ATAPI device. CloseHandle(hDevice); throw new Exception(string.Format("Drive {0} is a ATAPI device, we don''t detect it", driveIndex + 1)); } else { inParam.irDriveRegs.bCommandReg = 0xec; } inParam.bDriveNumber = driveIndex; inParam.irDriveRegs.bSectorCountReg = 1; inParam.irDriveRegs.bSectorNumberReg = 1; inParam.cBufferSize = 512; if (0 == DeviceIoControl( hDevice, DFP_RECEIVE_DRIVE_DATA, ref inParam, (uint)Marshal.SizeOf(inParam), ref outParam, (uint)Marshal.SizeOf(outParam), ref bytesReturned, IntPtr.Zero)) { CloseHandle(hDevice); throw new Exception("DeviceIoControl failed: DFP_RECEIVE_DRIVE_DATA"); } CloseHandle(hDevice); return GetHardDiskInfo(outParam.bBuffer); } /// /// 获取NT架构的硬盘信息 /// private static HardDiskInfo GetHddInfoNT(byte driveIndex) { GetVersionOutParams vers = new GetVersionOutParams(); SendCmdInParams inParam = new SendCmdInParams(); SendCmdOutParams outParam = new SendCmdOutParams(); uint bytesReturned = 0; // We start in NT/Win2000 IntPtr hDevice = CreateFile( string.Format(@"\\.\PhysicalDrive{0}", driveIndex), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero); if (hDevice == IntPtr.Zero) { throw new Exception("CreateFile faild."); } if (0 == DeviceIoControl( hDevice, DFP_GET_VERSION, IntPtr.Zero, 0, ref vers, (uint)Marshal.SizeOf(vers), ref bytesReturned, IntPtr.Zero)) { CloseHandle(hDevice); throw new Exception(string.Format("Drive {0} may not exists.", driveIndex + 1)); } // If IDE identify command not supported, fails if (0 == (vers.fCapabilities & 1)) { CloseHandle(hDevice); throw new Exception("Error: IDE identify command not supported."); } // Identify the IDE drives if (0 != (driveIndex & 1)) { inParam.irDriveRegs.bDriveHeadReg = 0xb0; } else { inParam.irDriveRegs.bDriveHeadReg = 0xa0; } if (0 != (vers.fCapabilities & (16 >> driveIndex))) { CloseHandle(hDevice); throw new Exception(string.Format("Drive {0} is a ATAPI device, we don''t detect it.", driveIndex + 1)); } else { inParam.irDriveRegs.bCommandReg = 0xec; } inParam.bDriveNumber = driveIndex; inParam.irDriveRegs.bSectorCountReg = 1; inParam.irDriveRegs.bSectorNumberReg = 1; inParam.cBufferSize = 512; if (0 == DeviceIoControl( hDevice, DFP_RECEIVE_DRIVE_DATA, ref inParam, (uint)Marshal.SizeOf(inParam), ref outParam, (uint)Marshal.SizeOf(outParam), ref bytesReturned, IntPtr.Zero)) { CloseHandle(hDevice); throw new Exception("DeviceIoControl failed: DFP_RECEIVE_DRIVE_DATA"); } CloseHandle(hDevice); return GetHardDiskInfo(outParam.bBuffer); } /// /// 获取硬盘信息的细节 /// /// /// private static HardDiskInfo GetHardDiskInfo(IdSector phdinfo) { HardDiskInfo hddInfo = new HardDiskInfo(); ChangeByteOrder(phdinfo.sModelNumber); hddInfo.ModuleNumber = Encoding.ASCII.GetString(phdinfo.sModelNumber).Trim(); ChangeByteOrder(phdinfo.sFirmwareRev); hddInfo.Firmware = Encoding.ASCII.GetString(phdinfo.sFirmwareRev).Trim(); ChangeByteOrder(phdinfo.sSerialNumber); hddInfo.SerialNumber = Encoding.ASCII.GetString(phdinfo.sSerialNumber).Trim(); hddInfo.Capacity = phdinfo.ulTotalAddressableSectors / 2 / 1024; return hddInfo; } /// /// 将byte数组中保存的信息转换成字符串 /// /// private static void ChangeByteOrder(byte[] charArray) { byte temp; for (int i = 0; i < charArray.Length; i += 2) { temp = charArray[i]; charArray[i] = charArray[i + 1]; charArray[i + 1] = temp; } } /// /// 获得硬盘信息 /// public static HardDiskInfo GetHDInfo(byte driveIndex) { switch (Environment.OSVersion.Platform) { case PlatformID.Win32Windows: return GetHddInfo9x(driveIndex); case PlatformID.Win32NT: return GetHddInfoNT(driveIndex); case PlatformID.Win32S: throw new NotSupportedException("Win32s is not supported."); case PlatformID.WinCE: throw new NotSupportedException("WinCE is not supported."); default: throw new NotSupportedException("Unknown Platform."); } } #endregion 获取硬盘信息的实现 #region 其他数据 /// /// 获取MAC地址 /// /// public static string GetMacAddress() { string mac = ""; ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration"); ManagementObjectCollection moc = mc.GetInstances(); foreach (ManagementObject mo in moc) { if ((bool)mo["IPEnabled"] == true) { mac = mo["MacAddress"].ToString(); break; } } return mac; } /// /// 获取IP地址 /// public static string GetIPAddress() { string st = ""; ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration"); ManagementObjectCollection moc = mc.GetInstances(); foreach (ManagementObject mo in moc) { if ((bool)mo["IPEnabled"] == true) { //st=mo["IpAddress"].ToString(); Array ar; ar = (Array)mo.Properties["IpAddress"].Value; st = ar.GetValue(0).ToString(); break; } } moc = null; mc = null; return st; } /// /// 获取操作系统的登录用户名 /// public static string GetUserName() { return Environment.UserName; } /// /// 获取计算机名 /// public static string GetComputerName() { return Environment.MachineName; } /// /// 获取PC类型 /// public static string GetSystemType() { string st = ""; ManagementClass mc = new ManagementClass("Win32_ComputerSystem"); ManagementObjectCollection moc = mc.GetInstances(); foreach (ManagementObject mo in moc) { st = mo["SystemType"].ToString(); } return st; } /// /// 获取物理内存 /// public static string GetTotalPhysicalMemory() { string st = ""; ManagementClass mc = new ManagementClass("Win32_ComputerSystem"); ManagementObjectCollection moc = mc.GetInstances(); foreach (ManagementObject mo in moc) { st = mo["TotalPhysicalMemory"].ToString(); } return st; } #endregion 其他数据 } }