NET获取硬盘序列号的几个方法文档格式.docx
- 文档编号:20073937
- 上传时间:2023-01-16
- 格式:DOCX
- 页数:18
- 大小:19.72KB
NET获取硬盘序列号的几个方法文档格式.docx
《NET获取硬盘序列号的几个方法文档格式.docx》由会员分享,可在线阅读,更多相关《NET获取硬盘序列号的几个方法文档格式.docx(18页珍藏版)》请在冰豆网上搜索。
//在Vista下面失败
ArrayListhdCollection=newArrayList();
ManagementObjectSearchersearcher=new
ManagementObjectSearcher("
SELECT*FROMWin32_DiskDrive"
);
foreach(ManagementObjectwmi_HDinsearcher.Get())
HardDrivehd=newHardDrive();
hd.Model=wmi_HD["
Model"
].ToString();
hd.Type=wmi_HD["
InterfaceType"
hdCollection.Add(hd);
searcher=new
SELECT*FROMWin32_PhysicalMedia"
inti=0;
//gettheharddrivefromcollection
//usingindex
HardDrivehd=(HardDrive)hdCollection[i];
//getthehardwareserialno.
if(wmi_HD["
SerialNumber"
]==null)
hd.SerialNo="
None"
;
else
hd.SerialNo=wmi_HD["
++i;
//Displayavailableharddrives
foreach(HardDrivehdinhdCollection)
Console.WriteLine("
Model\t\t:
"
+hd.Model);
Type\t\t:
+hd.Type);
SerialNo.\t:
+hd.SerialNo);
Console.WriteLine();
//Pauseapplication
Press[Enter]toexit..."
Console.ReadLine();
}
上面的方式先查询Win32_DiskDrive,然后再查询Win32_PhysicalMedia,经过测试,这种方式不能保证在所有机器上均取得硬盘序列号,而且在Vista下面还会出错,程序直接抛出无法处理的异常。
另外,还可以使用另外一WMI方式,就是查询PNPDeviceID的signature,代码如下:
///<
///获取硬盘唯一序列号(不是卷标号),可能需要以管理员身份运行程序
returns>
<
/returns>
publicstaticstringGetHdId()
ManagementObjectSearcherwmiSearcher=newManagementObjectSearcher();
/*
*PNPDeviceID的数据是由四部分组成的:
1、接口,通常有IDE,ATA,SCSI;
2、型号
3、(可能)驱动版本号
4、(可能)硬盘的出厂序列号
*
*/
//signature需要程序以管理员身份运行(经过测试,2003系统上非管理员身份也可以运行,查相关资料说,可能在2000系统上获取的值为空)
wmiSearcher.Query=newSelectQuery(
Win32_DiskDrive"
"
newstring[]{"
PNPDeviceID"
"
signature"
);
ManagementObjectCollectionmyCollection=wmiSearcher.Get();
ManagementObjectCollection.ManagementObjectEnumeratorem=
myCollection.GetEnumerator();
em.MoveNext();
ManagementBaseObjectmo=em.Current;
//stringid=mo.Properties["
].Value.ToString().Trim();
stringid=mo.Properties["
returnid;
有人说,使用signature需要程序以管理员身份运行(经过测试,2003系统上非管理员身份也可以运行),而且查询相关资料说,可能在2000系统上获取的值为空。
使用这种方式,在Vista上面工作良好。
经过测试,使用signature均能够取得硬盘序列号,但是跟Win32_PhysicalMedia查询出来的号不一样。
目前我也不能肯定使用signature能够100%取道硬盘序列号。
使用WMI方式需要客户机开启WMI服务,但这个往往不能保证,所以使用这种方式有一定局限性。
2,使用API方式。
在网上找到一片资料,说使用RING3调用APIDeviceIoControl()来获取硬盘信息,下面是原话:
硬盘序列号(SerialNumber)不等于卷标号(VolumeName),后者虽然很容易得到,但是格式化分区后就会重写,不可靠。
遗憾的是很多朋友往往分不清这一点。
要得到硬盘的物理序列号,可以通过WMI,也就是Win32_PhysicalMedia.SerialNumber。
可惜的是Windows98/ME的WMI并不支持这个类,访问时会出现异常。
受陆麟的例子的启发,我们还可以通过S.M.A.R.T.接口,直接从RING3调用APIDeviceIoControl()来获取硬盘信息,而不需要写VXD或者DRIVER。
这样这个问题就解决了,我对它进行了封装,大量使用了P/Invoke技术,一个完整的Library。
支持Windows98-2003。
使用上很简单:
HardDiskInfohdd=AtapiDevice.GetHddInfo(0);
//第一个硬盘
Console.WriteLine("
ModuleNumber:
{0}"
hdd.ModuleNumber);
SerialNumber:
hdd.SerialNumber);
Firmware:
hdd.Firmware);
Capacity:
{0}M"
hdd.Capacity);
感谢原文作者的贡献,(在这里我已经不知道原文作者是谁了,网上的文章都是转载的),经过测试,这种方式比较准确,但是需要管理员权限运行。
下面把代码分享:
usingSystem;
usingSystem.Runtime.InteropServices;
usingSystem.Text;
namespaceHardwareUtility
{
[Serializable]
publicstructHardDiskInfo
///型号
publicstringModuleNumber;
///固件版本
publicstringFirmware;
///序列号
publicstringSerialNumber;
///容量,以M为单位
publicuintCapacity;
#regionInternalStructs
[StructLayout(LayoutKind.Sequential,Pack=1)]
internalstructGetVersionOutParams
publicbytebVersion;
publicbytebRevision;
publicbytebReserved;
publicbytebIDEDeviceMap;
publicuintfCapabilities;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=4)]
publicuint[]dwReserved;
//Forfutureuse.
internalstructIdeRegs
publicbytebFeaturesReg;
publicbytebSectorCountReg;
publicbytebSectorNumberReg;
publicbytebCylLowReg;
publicbytebCylHighReg;
publicbytebDriveHeadReg;
publicbytebCommandReg;
internalstructSendCmdInParams
publicuintcBufferSize;
publicIdeRegsirDriveRegs;
publicbytebDriveNumber;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=3)]
publicbyte[]bReserved;
publicbytebBuffer;
internalstructDriverStatus
publicbytebDriverError;
publicbytebIDEStatus;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=2)]
internalstructSendCmdOutParams
publicDriverStatusDriverStatus;
publicIdSectorbBuffer;
[StructLayout(LayoutKind.Sequential,Pack=1,Size=512)]
internalstructIdSector
publicushortwGenConfig;
publicushortwNumCyls;
publicushortwReserved;
publicushortwNumHeads;
publicushortwBytesPerTrack;
publicushortwBytesPerSector;
publicushortwSectorsPerTrack;
publicushort[]wVendorUnique;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=20)]
publicbyte[]sSerialNumber;
publicushortwBufferType;
publicushortwBufferSize;
publicushortwECCSize;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=8)]
publicbyte[]sFirmwareRev;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=40)]
publicbyte[]sModelNumber;
publicushortwMoreVendorUnique;
publicushortwDoubleWordIO;
publicushortwCapabilities;
publicushortwReserved1;
publicushortwPIOTiming;
publicushortwDMATiming;
publicushortwBS;
publicushortwNumCurrentCyls;
publicushortwNumCurrentHeads;
publicushortwNumCurrentSectorsPerTrack;
publicuintulCurrentSectorCapacity;
publicushortwMultSectorStuff;
publicuintulTotalAddressableSectors;
publicushortwSingleWordDMA;
publicushortwMultiWordDMA;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=128)]
#endregion
///ATAPI驱动器相关
publicclassAtapiDevice
#regionDllImport
[DllImport("
kernel32.dll"
SetLastError=true)]
staticexternintCloseHandle(IntPtrhObject);
staticexternIntPtrCreateFile(
stringlpFileName,
uintdwDesiredAccess,
uintdwShareMode,
IntPtrlpSecurityAttributes,
uintdwCreationDisposition,
uintdwFlagsAndAttributes,
IntPtrhTemplateFile);
)]
staticexternintDeviceIoControl(
IntPtrhDevice,
uintdwIoControlCode,
IntPtrlpInBuffer,
uintnInBufferSize,
refGetVersionOutParamslpOutBuffer,
uintnOutBufferSize,
refuintlpBytesReturned,
[Out]IntPtrlpOverlapped);
refSendCmdInParamslpInBuffer,
refSendCmdOutParamslpOutBuffer,
constuintDFP_GET_VERSION=0x00074080;
constuintDFP_SEND_DRIVE_COMMAND=0x0007c084;
constuintDFP_RECEIVE_DRIVE_DATA=0x0007c088;
constuintGENERIC_READ=0x80000000;
constuintGENERIC_WRITE=0x40000000;
constuintFILE_SHARE_READ=0x00000001;
constuintFILE_SHARE_WRITE=0x00000002;
constuintCREATE_NEW=1;
constuintOPEN_EXISTING=3;
#regionGetHddInfo
///获得硬盘信息
paramname="
driveIndex"
>
硬盘序号<
/param>
硬盘信息<
remarks>
///参考lu0的文章:
http:
//lu0s1.3322.org/App/2k1103.html
///bysunmastforeveryone
///thankslu0forhisgreatworks
///在Windows98/ME中,S.M.A.R.T并不缺省安装,请将SMARTVSD.VXD拷贝到%SYSTEM%\IOSUBSYS目录下。
///在Windows2000/2003下,需要Administrators组的权限。
/remarks>
example>
///AtapiDevice.GetHddInfo()
/example>
publicstaticHardDiskInfoGetHddInfo(bytedriveIndex)
switch(Environment.OSVersion.Platform)
casePlatformID.Win32Windows:
returnGetHddInfo9x(driveIndex);
casePlatformID.Win32NT:
returnGetHddInfoNT(driveIndex);
casePlatformID.Win32S:
thrownewNotSupportedException("
Win32sisnotsupported."
casePlatformID.WinCE:
WinCEisnotsupported."
default:
UnknownPlatform."
#regionGetHddInfo9x
privatestaticHardDiskInfoGetHddInfo9x(bytedriveIndex)
GetVersionOutParamsvers=newGetVersionOutParams();
SendCmdInP
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- NET 获取 硬盘 序列号 几个 方法