获取U盘序列号的实现方法

本文介绍了一种通过Windows API函数获取连接到系统的USB磁盘ID的方法,并提供了完整的Delphi实现代码。该方法利用了SetupAPI函数来枚举设备接口并找到与指定驱动器路径匹配的USB设备。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Uses Registry;

Const
  DIGCF_PRESENT = $00000002;
  DIGCF_DEVICEINTERFACE = $00000010;
  ANYSIZE_ARRAY = 1;
  SetupAPI = 'SetupAPI.DLL';

Type
  HDEVINFO = Pointer;
  ULONG_PTR = DWORD;

  PSPDevInfoData = ^TSPDevInfoData;
  SP_DEVINFO_DATA = Packed Record
    cbSize: DWORD;
    ClassGuid: TGUID;
    DevInst: DWORD;
    Reserved: ULONG_PTR;
  End;
  {$EXTERNALSYM SP_DEVINFO_DATA}
  TSPDevInfoData = SP_DEVINFO_DATA;

  PSPDeviceInterfaceData = ^TSPDeviceInterfaceData;
  SP_DEVICE_INTERFACE_DATA = Packed Record
    cbSize: DWORD;
    InterfaceClassGuid: TGUID;
    Flags: DWORD;
    Reserved: ULONG_PTR;
  End;
  {$EXTERNALSYM SP_DEVICE_INTERFACE_DATA}
  TSPDeviceInterfaceData = SP_DEVICE_INTERFACE_DATA;

  PSPDeviceInterfaceDetailDataA = ^TSPDeviceInterfaceDetailDataA;
  SP_DEVICE_INTERFACE_DETAIL_DATA_A = Packed Record
    cbSize: DWORD;
    DevicePath: Array[0..ANYSIZE_ARRAY - 1] Of AnsiChar;
  End;
  {$EXTERNALSYM SP_DEVICE_INTERFACE_DETAIL_DATA_A}
  TSPDeviceInterfaceDetailDataA = SP_DEVICE_INTERFACE_DETAIL_DATA_A;

Function SetupDiGetClassDevsA(ClassGuid: PGUID; Const Enumerator: PAnsiChar;
  hwndParent: HWND; Flags: DWORD): HDEVINFO; Stdcall; External SetupAPI;

Function SetupDiEnumDeviceInterfaces(DeviceInfoSet: HDEVINFO;
  DeviceInfoData: PSPDevInfoData; Const InterfaceClassGuid: TGUID;
  MemberIndex: DWORD; Var DeviceInterfaceData: TSPDeviceInterfaceData): BOOL; Stdcall; External SetupAPI;
{$EXTERNALSYM SetupDiEnumDeviceInterfaces}

Function SetupDiGetDeviceInterfaceDetailA(DeviceInfoSet: HDEVINFO;
  DeviceInterfaceData: PSPDeviceInterfaceData;
  DeviceInterfaceDetailData: PSPDeviceInterfaceDetailDataA;
  DeviceInterfaceDetailDataSize: DWORD; Var RequiredSize: DWORD;
  Device: PSPDevInfoData): BOOL; Stdcall; External SetupAPI;

Function SetupDiDestroyDeviceInfoList(DeviceInfoSet: HDEVINFO): BOOL; Stdcall; External SetupAPI;

Function GetUSBDiskID(DiskID: String; Var PID: String): Boolean;
Var
  USBGuid: TGUID;
  USBHandle: HDEVINFO;
  Success: LongBool;
  Devn: Integer;
  DevData: TSPDevInfoData;
  DeviceInterfaceData: TSPDeviceInterfaceData;
  FunctionClassDeviceData: PSPDeviceInterfaceDetailDataA;
  BytesReturned: DWORD;
  Reg: TRegistry;
  RegData: Array Of Char;
  i, RegSize: Integer;
  Str, USBPath: String;
Begin
  Result := false;
  Pid := '';
  Reg := TRegistry.Create;
  Reg.RootKey := HKEY_LOCAL_MACHINE;
  Reg.OpenKey('SYSTEM/MountedDevices', false);
  RegSize := Reg.GetDataSize(Format('/DosDevices/%s', [DiskID]));
  SetLength(RegData, RegSize + 1);
  Reg.ReadBinaryData(Format('/DosDevices/%s', [DiskID]), RegData[0], RegSize + 1);
  For i := 0 To RegSize - 1 Do
    If RegData[i] <> #0 Then Str := Str + RegData[i];
  Str := Copy(Str, Pos('#RemovableMedia#', Str) + 16, Length(Str));
  Str := Copy(Str, 1, Pos('RM', Str) - 2);
  Str := UpperCase(Str);
  Reg.CloseKey;

  USBGuid := StringToGUID('{53f56307-b6bf-11d0-94f2-00a0c91efb8b}');
  USBHandle := SetupDiGetClassDevsA(@USBGuid, Nil, 0, DIGCF_PRESENT Or DIGCF_DEVICEINTERFACE);
  If USBHandle = Pointer(INVALID_HANDLE_VALUE) Then Exit;
  Devn := 0;
  Repeat
    DeviceInterfaceData.cbSize := SizeOf(TSPDeviceInterfaceData);
    Success := SetupDiEnumDeviceInterfaces(USBHandle, Nil, USBGuid, Devn, DeviceInterfaceData);
    If Success Then
    Begin
      DevData.cbSize := SizeOf(DevData);
      BytesReturned := 0;
      SetupDiGetDeviceInterfaceDetailA(USBHandle, @DeviceInterfaceData, Nil, 0, BytesReturned, @DevData);
      If (BytesReturned <> 0) And (GetLastError = ERROR_INSUFFICIENT_BUFFER) Then
      Begin
        FunctionClassDeviceData := AllocMem(BytesReturned);
        FunctionClassDeviceData^.cbSize := SizeOf(TSPDeviceInterfaceDetailDataA);
        If SetupDiGetDeviceInterfaceDetailA(USBHandle, @DeviceInterfaceData,
          FunctionClassDeviceData, BytesReturned, BytesReturned, @DevData) Then
        Begin
          USBPath := StrPas(PChar(@FunctionClassDeviceData.DevicePath));
          If Reg.OpenKeyReadOnly(Format('SYSTEM/CurrentControlSet/Enum%s', [StringReplace(Copy(USBPath, 4, Pos('{', USBPath) - 5), '#', '/', [rfReplaceAll])])) Then
          If UpperCase(Reg.ReadString('ParentIdPrefix')) = Str Then
          Begin
          PID := StringReplace(Str, '&', '', [rfReplaceAll]);
          Result := True;
          Break;
          End;
          Reg.CloseKey;
          Inc(Devn);
        End;
        FreeMem(FunctionClassDeviceData);
      End;
    End;
  Until Not Success;
  SetupDiDestroyDeviceInfoList(USBHandle);
  Reg.Free;
End;

//使用方法
Procedure TForm1.Button1Click(Sender: TObject);
Var
  Drv, Pid: String;
Begin
  Drv := ExtractFileDrive(ParamStr(0));
  If GetDriveType(PChar(Drv + '/')) <> DRIVE_REMOVABLE Then
    Application.MessageBox('对不起,请把本程序放至到U盘上使用!', 'Error', MB_ICONHAND)
  Else
    If GetUSBDiskID(Drv, Pid) Then Memo1.Lines.Add(Pid);
End; 

获取UID序列号 VS2005编译通过,源码源自优快云。已经测试好用。 可以获得U名称,制造商ID号 版本号 U序列号及容量 Form1.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.IO; using System.Management; namespace UDiskTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button2_Click(object sender, EventArgs e) { DriveInfo[] s = DriveInfo.GetDrives(); foreach (DriveInfo drive in s) { if (drive.DriveType == DriveType.Removable) { pf.Text = drive.Name.ToString(); break; } } ManagementClass cimobject = new ManagementClass("Win32_DiskDrive"); ManagementObjectCollection moc = cimobject.GetInstances(); foreach (ManagementObject mo in moc) { if (mo.Properties["InterfaceType"].Value.ToString() == "USB") { try { //产品名称 Caption.Text = mo.Properties["Caption"].Value.ToString(); //总容量 Size.Text = mo.Properties["Size"].Value.ToString(); string[] info = mo.Properties["PNPDeviceID"].Value.ToString().Split('&'); string[] xx = info[3].Split('\\'); //序列号 MessageBox.Show("U序列号:" + xx[1]); PNPDeviceID.Text = xx[1]; xx = xx[0].Split('_'); //版本号 REV.Text = xx[1]; //制造商ID xx = info[1].Split('_'); VID.Text = xx[1]; } catch (Exception ex) { MessageBox.Show(ex.Message); } } } } } } 如果编译遇到问题是using System.Management;无法找到引用找到, 项目(p)->添加引用(R)->找到.NET标签页 列表中下部位找到System.Management 双击点确定
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值