NET获取硬盘序列号的几个方法.docx

上传人:b****6 文档编号:7048551 上传时间:2023-01-16 格式:DOCX 页数:18 大小:19.72KB
下载 相关 举报
NET获取硬盘序列号的几个方法.docx_第1页
第1页 / 共18页
NET获取硬盘序列号的几个方法.docx_第2页
第2页 / 共18页
NET获取硬盘序列号的几个方法.docx_第3页
第3页 / 共18页
NET获取硬盘序列号的几个方法.docx_第4页
第4页 / 共18页
NET获取硬盘序列号的几个方法.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

NET获取硬盘序列号的几个方法.docx

《NET获取硬盘序列号的几个方法.docx》由会员分享,可在线阅读,更多相关《NET获取硬盘序列号的几个方法.docx(18页珍藏版)》请在冰豆网上搜索。

NET获取硬盘序列号的几个方法.docx

NET获取硬盘序列号的几个方法

最近作软件注册,收集了很多.NET相关的获取硬盘物理序列号的方法,主要分为使用WMI方式和API方式。

但这些方法均可能有问题。

1,使用WMI方式,有的机器根本取不到硬盘序列号,有的方式在Vista下面会报错。

常用的使用WMI的方式主要有下面一些方式:

classHardDrive

{

privatestringmodel=null;

privatestringtype=null;

privatestringserialNo=null;

publicstringModel

{

get{returnmodel;}

set{model=value;}

}

publicstringType

{

get{returntype;}

set{type=value;}

}

publicstringSerialNo

{

get{returnserialNo;}

set{serialNo=value;}

}

}

classTestProgram

{

///

///Themainentrypointfortheapplication.

///

[STAThread]

staticvoidMain(string[]args)

{

//在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"].ToString();

hdCollection.Add(hd);

}

searcher=new

ManagementObjectSearcher("SELECT*FROMWin32_PhysicalMedia");

inti=0;

foreach(ManagementObjectwmi_HDinsearcher.Get())

{

//gettheharddrivefromcollection

//usingindex

HardDrivehd=(HardDrive)hdCollection[i];

//getthehardwareserialno.

if(wmi_HD["SerialNumber"]==null)

hd.SerialNo="None";

else

hd.SerialNo=wmi_HD["SerialNumber"].ToString();

++i;

}

//Displayavailableharddrives

foreach(HardDrivehdinhdCollection)

{

Console.WriteLine("Model\t\t:

"+hd.Model);

Console.WriteLine("Type\t\t:

"+hd.Type);

Console.WriteLine("SerialNo.\t:

"+hd.SerialNo);

Console.WriteLine();

}

//Pauseapplication

Console.WriteLine("Press[Enter]toexit...");

Console.ReadLine();

}

}

上面的方式先查询Win32_DiskDrive,然后再查询Win32_PhysicalMedia,经过测试,这种方式不能保证在所有机器上均取得硬盘序列号,而且在Vista下面还会出错,程序直接抛出无法处理的异常。

 

另外,还可以使用另外一WMI方式,就是查询PNPDeviceID的signature,代码如下:

///

///获取硬盘唯一序列号(不是卷标号),可能需要以管理员身份运行程序

///

///

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["PNPDeviceID"].Value.ToString().Trim();

stringid=mo.Properties["signature"].Value.ToString().Trim();

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);

Console.WriteLine("SerialNumber:

{0}",hdd.SerialNumber);

Console.WriteLine("Firmware:

{0}",hdd.Firmware);

Console.WriteLine("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.

}

[StructLayout(LayoutKind.Sequential,Pack=1)]

internalstructIdeRegs

{

publicbytebFeaturesReg;

publicbytebSectorCountReg;

publicbytebSectorNumberReg;

publicbytebCylLowReg;

publicbytebCylHighReg;

publicbytebDriveHeadReg;

publicbytebCommandReg;

publicbytebReserved;

}

[StructLayout(LayoutKind.Sequential,Pack=1)]

internalstructSendCmdInParams

{

publicuintcBufferSize;

publicIdeRegsirDriveRegs;

publicbytebDriveNumber;

[MarshalAs(UnmanagedType.ByValArray,SizeConst=3)]

publicbyte[]bReserved;

[MarshalAs(UnmanagedType.ByValArray,SizeConst=4)]

publicuint[]dwReserved;

publicbytebBuffer;

}

[StructLayout(LayoutKind.Sequential,Pack=1)]

internalstructDriverStatus

{

publicbytebDriverError;

publicbytebIDEStatus;

[MarshalAs(UnmanagedType.ByValArray,SizeConst=2)]

publicbyte[]bReserved;

[MarshalAs(UnmanagedType.ByValArray,SizeConst=2)]

publicuint[]dwReserved;

}

[StructLayout(LayoutKind.Sequential,Pack=1)]

internalstructSendCmdOutParams

{

publicuintcBufferSize;

publicDriverStatusDriverStatus;

publicIdSectorbBuffer;

}

[StructLayout(LayoutKind.Sequential,Pack=1,Size=512)]

internalstructIdSector

{

publicushortwGenConfig;

publicushortwNumCyls;

publicushortwReserved;

publicushortwNumHeads;

publicushortwBytesPerTrack;

publicushortwBytesPerSector;

publicushortwSectorsPerTrack;

[MarshalAs(UnmanagedType.ByValArray,SizeConst=3)]

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)]

publicbyte[]bReserved;

}

#endregion

///

///ATAPI驱动器相关

///

publicclassAtapiDevice

{

#regionDllImport

[DllImport("kernel32.dll",SetLastError=true)]

staticexternintCloseHandle(IntPtrhObject);

[DllImport("kernel32.dll",SetLastError=true)]

staticexternIntPtrCreateFile(

stringlpFileName,

uintdwDesiredAccess,

uintdwShareMode,

IntPtrlpSecurityAttributes,

uintdwCreationDisposition,

uintdwFlagsAndAttributes,

IntPtrhTemplateFile);

[DllImport("kernel32.dll")]

staticexternintDeviceIoControl(

IntPtrhDevice,

uintdwIoControlCode,

IntPtrlpInBuffer,

uintnInBufferSize,

refGetVersionOutParamslpOutBuffer,

uintnOutBufferSize,

refuintlpBytesReturned,

[Out]IntPtrlpOverlapped);

[DllImport("kernel32.dll")]

staticexternintDeviceIoControl(

IntPtrhDevice,

uintdwIoControlCode,

refSendCmdInParamslpInBuffer,

uintnInBufferSize,

refSendCmdOutParamslpOutBuffer,

uintnOutBufferSize,

refuintlpBytesReturned,

[Out]IntPtrlpOverlapped);

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;

#endregion

#regionGetHddInfo

///

///获得硬盘信息

///

///硬盘序号

///硬盘信息

///

///参考lu0的文章:

http:

//lu0s1.3322.org/App/2k1103.html

///bysunmastforeveryone

///thankslu0forhisgreatworks

///在Windows98/ME中,S.M.A.R.T并不缺省安装,请将SMARTVSD.VXD拷贝到%SYSTEM%\IOSUBSYS目录下。

///在Windows2000/2003下,需要Administrators组的权限。

///

///

///AtapiDevice.GetHddInfo()

///

publicstaticHardDiskInfoGetHddInfo(bytedriveIndex)

{

switch(Environment.OSVersion.Platform)

{

casePlatformID.Win32Windows:

returnGetHddInfo9x(driveIndex);

casePlatformID.Win32NT:

returnGetHddInfoNT(driveIndex);

casePlatformID.Win32S:

thrownewNotSupportedException("Win32sisnotsupported.");

casePlatformID.WinCE:

thrownewNotSupportedException("WinCEisnotsupported.");

default:

thrownewNotSupportedException("UnknownPlatform.");

}

}

#regionGetHddInfo9x

privatestaticHardDiskInfoGetHddInfo9x(bytedriveIndex)

{

GetVersionOutParamsvers=newGetVersionOutParams();

SendCmdInP

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1