各位老師:
   小弟現在要寫一只測試測試,當我插入U盤時,自動讀取其設備的基本資料描述,如PID,VID,SERIALNO,等,我在網上找了很多資料編譯時不是少這樣就是少那樣,無法編譯成功,請各位大大指教,功能就跟USBview相似,最好是DELPhi寫的。謝謝
急,等待中!
    

解决方案 »

  1.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        Memo1: TMemo;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}uses
      ExtCtrls,ActiveX, ComObj;procedure TForm1.Button1Click(Sender: TObject);
    var
      Locator: OleVariant;
      WMI: OleVariant;
      RET: OleVariant;
      Enum: IEnumVariant;
      Tmp: OleVariant;
      Value: Cardinal;
    begin;
      Memo1.Clear;
      Locator := CreateOleObject('WbemScripting.SWbemLocator');
      WMI := Locator.ConnectServer('.', '', '', '');
      Ret := WMI.ExecQuery('SELECT * FROM Win32_USBHub');//这里Win32_USBHub为检测项,详见下表  Enum:= IUnknown(RET._NewEnum) as IEnumVariant;
      while (Enum.Next(1, Tmp, Value) = S_OK) do
      begin
        if Tmp.Name='USB Mass Storage Device' then
    //      ShowMessage('这个u盘的硬件特徵码是'+Tmp.PNPDeviceID);//Tmp为检测到返回的数据集合,其中PNPDeviceID为集合中的对象,包含了PID和VID码
          Memo1.Lines.Add(Tmp.PNPDeviceID);
      end;
      Memo1.Lines.Add('Finish');
    end;
      

  2.   

    type
      TForm1 = class(TForm)
        Label1: TLabel;
      private
        procedure WMDeviceChange(var Msg: TMessage); message WM_DEVICECHANGE; //u盘插入消息
      public
      end;var
      Form1: TForm1;implementation{$R   *.dfm}procedure TForm1.WMDeviceChange(var Msg: TMessage);
    var
      myMsg: string;
    begin
      case Msg.WParam of
        32768:
          begin
            myMsg := 'U盘插入';
            Label1.Caption := myMsg
          end;
        32772:
          begin
            myMsg := 'U盘拔出';
            Label1.Caption := myMsg;
          end;
      end;
    end;
      

  3.   

    oosmile:
       謝謝
      但是我測試了一下有些U盤根本抓不了資料,主要是想要以下這些基本信息
    (這個是從USBVIEW中抓取的,我想寫程式自己實現,以便我後續的動作)Device Descriptor:
    bcdUSB:             0x0200
    bDeviceClass:         0x00
    bDeviceSubClass:      0x00
    bDeviceProtocol:      0x00
    bMaxPacketSize0:      0x40 (64)
    idVendor:           0x0951 (Kingston Technology Company)
    idProduct:          0x1603
    bcdDevice:          0x0200
    iManufacturer:        0x01
    0x0409: "Kingston"
    iProduct:             0x02
    0x0409: "DataTraveler 2.0"
    iSerialNumber:        0x03
    0x0409: "988000000000000045B46868"
    bNumConfigurations:   0x01你有什么好的方法嗎?
      

  4.   

    Win32_USBHub里面有这些信息,msdn里面的说明,你可以看看http://msdn.microsoft.com/en-us/library/aa394506.aspxclass Win32_USBHub : CIM_USBHub
    {
      uint16 Availability;
      string Caption;
      uint8 ClassCode;
      uint32 ConfigManagerErrorCode;
      boolean ConfigManagerUserCode;
      string CreationClassName;
      uint8 CurrentAlternativeSettings;
      uint8 CurrentConfigValue;
      string Description;
      string DeviceID;
      boolean ErrorCleared;
      string ErrorDescription;
      boolean GangSwitched;
      datetime InstallDate;
      uint32 LastErrorCode;
      string Name;
      uint8 NumberOfConfigs;
      uint8 NumberOfPorts;
      string PNPDeviceID;
      uint16 PowerManagementCapabilities[];
      boolean PowerManagementSupported;
      uint8 ProtocolCode;
      string Status;
      uint16 StatusInfo;
      uint8 SubclassCode;
      string SystemCreationClassName;
      string SystemName;
      uint16 USBVersion;
    };
      

  5.   

    oosmile:
      謝謝 
      我在網上找到這麼一段程式,但是編譯時出現Access violation at address 錯誤unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs,StdCtrls;const   
              DIGCF_PRESENT   =   2;   
              DIGCF_INTERFACEDEVICE   =   16;   
    type
        
        PSP_DEVINFO_DATA   =   ^SP_DEVINFO_DATA;   
        SP_DEVINFO_DATA   =   packed   record   
              cbSize   :DWORD;   
              ClassGuid   :TGUID;   
              DevInst   :DWORD   ;         //   DEVINST   handle   
              Reserved   :DWORD;   
        end;   
        
          HDEVINFO   =   Pointer;   
        
          pulong   =   ^ulong;   
        
          PSP_INTERFACE_DEVICE_DATA   =   ^SP_INTERFACE_DEVICE_DATA;   
          SP_INTERFACE_DEVICE_DATA   =   packed   record   
                cbSize   :ulong;   
                InterfaceClassGuid   :   TGuid;   
                Flags     :ulong;   
                Reserved   :ulong;   
          end;   
        
          PSP_INTERFACE_DEVICE_DETAIL_DATA   =   ^PSP_INTERFACE_DEVICE_DETAIL_DATA;   
          SP_DEVICE_INTERFACE_DETAIL_DATA   =   packed   record   
              cbSize   :DWORD;
              DevicePath:   Char;
          end;   
        
        
        PUSB_DEVICE_DESCRIPTOR   =   ^USB_DEVICE_DESCRIPTOR;   
        USB_DEVICE_DESCRIPTOR     =   packed   record   
            bLength   :UCHAR;   
            bDescriptorType   :UCHAR;   
            bcdUSB   :WORD;   
            bDeviceClass   :UCHAR;   
            bDeviceSubClass   :UCHAR;   
            bDeviceProtocol   :UCHAR;   
            bMaxPacketSize0   :UCHAR;   
            idVendor   :Word;   
            idProduct   :Word;   
            bcdDevice   :Word;   
            iManufacturer   :UCHAR;   
            iProduct   :UCHAR;   
            iSerialNumber   :UCHAR;   
            bNumConfigurations   :UCHAR;   
          end;   
        
      function   SetupDiGetDeviceInterfaceDetail(   
            DeviceInfoSet   :   HDEVINFO;   
            DeviceInterfaceData:     PSP_INTERFACE_DEVICE_DATA;   
            DeviceInterfaceDetailData:     PSP_INTERFACE_DEVICE_DETAIL_DATA;   
            DeviceInterfaceDetailDataSize   :   DWORD;   
            RequiredSize   :   PDWORD;   
            DeviceInfoData   :   PSP_DEVINFO_DATA):   BOOL;   stdcall;   external   'SETUPAPI.dll'   name   'SetupDiGetDeviceInterfaceDetailA';
        
      function   SetupDiGetClassDevsEx(   
                ClassGuid   :PGUID;   
              Enumerator   :PChar;
              hwndParent   :HWND;   
              Flags   :   DWORD;
              MachineName   :PChar;
              Reserved   :Pointer   
              ):   HDEVINFO;   stdcall;   external   'SETUPAPI.dll'   name   'SetupDiGetClassDevsExA';   
        
      function   SetupDiGetClassDevs(   
              ClassGuid   :PGUID   ;   
              Enumerator:   PChar;   
              hwndParent:   HWND;   
              Flags   :   DWORD   
              ):   HDEVINFO;   stdcall;   external   'SETUPAPI.dll'   name   'SetupDiGetClassDevsA';   
        
      function   SetupDiEnumDeviceInterfaces(   
                  DeviceInfoSet   :HDEVINFO;   
                  DeviceInfoData   :PSP_DEVINFO_DATA;   
                  InterfaceClassGuid   :PGUID;   
                  MemberIndex   :DWORD;   
                  DeviceInterfaceData   :PSP_INTERFACE_DEVICE_DATA   
              ):   BOOL;   stdcall;   external   'SETUPAPI.dll'   name   'SetupDiEnumDeviceInterfaces';   
        
      function   SetupDiDestroyDeviceInfoList(   
                    DeviceInfoSet   :HDEVINFO   
              ):BOOL;   stdcall;   external   'SETUPAPI.dll'   name   'SetupDiEnumDeviceInterfaces';   
        
      type   
          TOnGetStrEvent   =   procedure(AStr   :string)   of   object;     const
                  USBIODS_GUID   :   TGuid   =   '{a5dcbf10-6530-11d2-901f-00c04fb951ed}';
    type
      TForm1 = class(TForm)
        Button1: TButton;
        Memo1: TMemo;
        Edit1: TEdit;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      function split(s,s1:string):TStringList;
    implementation{$R *.dfm}
    function split(s,s1:string):TStringList;
    begin
      Result:=TStringList.Create;
      while Pos(s1,s)>0 do
      begin
         Result.Add(Copy(s,1,Pos(s1,s)-1));
         Delete(s,1,Pos(s1,s));
      end;
      Result.Add(s);
    end;procedure TForm1.Button1Click(Sender: TObject);
    var   b   :integer;   
              bRst   :BOOL;   
              hInfo   :HDEVINFO;   
      //         USBIODS_GUID   :TGuid;   
              deviceInterfaceData   :SP_INTERFACE_DEVICE_DATA;   
              DeviceDetailData   :SP_DEVICE_INTERFACE_DETAIL_DATA;   
        
              predictedLength   :   ULONG;   
              requiredLength     :ULONG;   
              nCount:   integer;
              s1:TStringList;
              ss:pchar;
      begin   
              Memo1.Clear;
              predictedLength   :=   0;   
              requiredLength   :=   0;   
              hInfo   :=   nil;   
              hInfo   :=   SetupDiGetClassDevs(@USBIODS_GUID,   nil,   0,DIGCF_PRESENT   OR   DIGCF_INTERFACEDEVICE);
        
              bRst   :=   true;   
              nCount   :=   0;   
        
              deviceInterfaceData.cbSize   :=   Sizeof(SP_INTERFACE_DEVICE_DATA);   
              DeviceDetailData.cbSize   :=   sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
        
              if   hInfo   =   nil   then   
              begin   
                  showmessage('failed   0');   
                  exit;   
              end;   
        
              while   bRst   do
              begin   
                  deviceInterfaceData.cbSize   :=   Sizeof(deviceInterfaceData);   
        
                  bRst   :=   SetupDiEnumDeviceInterfaces(hInfo,   nil,   @USBIODS_GUID,nCount,   @deviceInterfaceData);
        
      if   bRst   then
       begin
        SetupDiGetDeviceInterfaceDetail(hInfo,   @deviceInterfaceData, nil,   0,   @requiredLength,   nil);
        predictedLength   :=   requiredLength;
        DeviceDetailData.cbSize   :=   sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
        bRst   :=   SetupDiGetDeviceInterfaceDetail(hInfo,   @deviceInterfaceData,@DeviceDetailData,   predictedLength,   @requiredLength,   nil);
        
                        if   bRst   then
                        begin
                        ss:=PChar(@(DeviceDetailData.DevicePath));
                       showmessage(strpas(ss));
                                   Inc(nCount);
                        end;   
                  end;
              end;  end; 
    end.但是卻不能這樣表達,我無法從中split想要的資料,請你幫看看edit1.Text :=strpas(ss);這樣表達就會出現以上同樣的錯誤
      

  6.   

    var
      USBHandle: HDEVINFO;
      Success: LongBool;
      Devn: Integer;
      DevData: SP_DEVINFO_DATA;
      DeviceInterfaceData: SP_INTERFACE_DEVICE_DATA;
      FunctionClassDeviceData: PSP_INTERFACE_DEVICE_DETAIL_DATA;
      BytesReturned: DWORD;
      ss: PChar;
      USBPath: string;
      i: Integer;
      Vid, Pid, No: string;
    begin  Memo1.Clear;  USBHandle := SetupDiGetClassDevsA(@USBIODS_GUID, nil, 0, DIGCF_PRESENT or DIGCF_INTERFACEDEVICE);
      if USBHandle = Pointer(INVALID_HANDLE_VALUE) then exit;
      Devn := 0;
      repeat
        DeviceInterfaceData.cbSize := Sizeof(SP_INTERFACE_DEVICE_DATA);
        Success := SetupDiEnumDeviceInterfaces(USBHandle, nil, @USBIODS_GUID, 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(SP_DEVICE_INTERFACE_DETAIL_DATA);
            if SetupDiGetDeviceInterfaceDetailA(USBHandle, @DeviceInterfaceData, FunctionClassDeviceData, BytesReturned, @BytesReturned, @DevData) then
            begin
              USBPath := StrPas(PChar(@FunctionClassDeviceData.DevicePath));
              USBPath := Format('%s', [StringReplace(Copy(USBPath, 4, Pos('{', USBPath) - 5), '#', '\', [rfReplaceAll])]);          Memo1.Lines.Add(USBPath);          Edit1.Text :=  USBPath;        end;
          end;
        end;
      until not Success;end;
      

  7.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;const
      DIGCF_PRESENT = 2;
      DIGCF_INTERFACEDEVICE = 16;
    type  PSP_DEVINFO_DATA = ^SP_DEVINFO_DATA;
      SP_DEVINFO_DATA = packed record
        cbSize: DWORD;
        ClassGuid: TGUID;
        DevInst: DWORD; //  DEVINST  handle
        Reserved: DWORD;
      end;  HDEVINFO = Pointer;
      PSP_INTERFACE_DEVICE_DATA = ^SP_INTERFACE_DEVICE_DATA;
      SP_INTERFACE_DEVICE_DATA = packed record
        cbSize: ulong;
        InterfaceClassGuid: TGUID;
        Flags: ulong;
        Reserved: ulong;
      end;  PSP_INTERFACE_DEVICE_DETAIL_DATA = ^SP_DEVICE_INTERFACE_DETAIL_DATA;
      SP_DEVICE_INTERFACE_DETAIL_DATA = packed record
        cbSize: DWORD;
        DevicePath: Char;
      end;function SetupDiGetDeviceInterfaceDetailA(
      DeviceInfoSet: HDEVINFO;
      DeviceInterfaceData: PSP_INTERFACE_DEVICE_DATA;
      DeviceInterfaceDetailData: PSP_INTERFACE_DEVICE_DETAIL_DATA;
      DeviceInterfaceDetailDataSize: DWORD;
      RequiredSize: PDWORD;
      DeviceInfoData: PSP_DEVINFO_DATA): BOOL; stdcall; external 'SETUPAPI.dll';
    function SetupDiGetClassDevsA(
      ClassGuid: PGUID;
      Enumerator: PChar;
      hwndParent: HWND;
      Flags: DWORD
      ): HDEVINFO; stdcall; external 'SETUPAPI.dll';function SetupDiEnumDeviceInterfaces(
      DeviceInfoSet: HDEVINFO;
      DeviceInfoData: PSP_DEVINFO_DATA;
      InterfaceClassGuid: PGUID;
      MemberIndex: DWORD;
      DeviceInterfaceData: PSP_INTERFACE_DEVICE_DATA
      ): BOOL; stdcall; external 'SETUPAPI.dll';
    const
      USBIODS_GUID: TGUID = '{a5dcbf10-6530-11d2-901f-00c04fb951ed}';
      

  8.   

    var
      USBHandle: HDEVINFO;
      Success: LongBool;
      Devn: Integer;
      DevData: SP_DEVINFO_DATA;
      DeviceInterfaceData: SP_INTERFACE_DEVICE_DATA;
      FunctionClassDeviceData: PSP_INTERFACE_DEVICE_DETAIL_DATA;
      BytesReturned: DWORD;
      ss: PChar;
      USBPath: string;
      i: Integer;
      Vid, Pid, No: string;
    begin  Memo1.Clear;  USBHandle := SetupDiGetClassDevsA(@USBIODS_GUID, nil, 0, DIGCF_PRESENT or DIGCF_INTERFACEDEVICE);
      if USBHandle = Pointer(INVALID_HANDLE_VALUE) then
      begin
        //ShowMessage('Could not attach to usb node');
        Exit;
      end;  Devn := 0;
      repeat
        DeviceInterfaceData.cbSize := Sizeof(SP_INTERFACE_DEVICE_DATA);
        Success := SetupDiEnumDeviceInterfaces(USBHandle, nil, @USBIODS_GUID, Devn, @DeviceInterfaceData);
        if Success then
        begin
          DevData.cbSize := Sizeof(DevData);
          FunctionClassDeviceData := nil;
          BytesReturned := 0;
          SetupDiGetDeviceInterfaceDetailA(USBHandle, @DeviceInterfaceData, nil, 0, @BytesReturned, nil); //@DevData);
          if (BytesReturned <> 0) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
          begin
            FunctionClassDeviceData := AllocMem(BytesReturned);
            FunctionClassDeviceData^.cbSize := Sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
            if SetupDiGetDeviceInterfaceDetailA(USBHandle, @DeviceInterfaceData, FunctionClassDeviceData, BytesReturned, @BytesReturned, nil) then // @DevData) then
            begin
              USBPath := StrPas(PChar(@FunctionClassDeviceData.DevicePath));
              USBPath := Format('%s', [StringReplace(Copy(USBPath, 4, Pos('{', USBPath) - 5), '#', '\', [rfReplaceAll])]);          Memo1.Lines.Add(USBPath);          Edit1.Text := USBPath;        end
            else
            begin
              //ShowMessage('Could not find the system name for this HID device');
              Exit;//
            end;
            Inc(Devn);//
            FreeMem(FunctionClassDeviceData);//
          end;
        end;
      until not Success;end;
      

  9.   

    oosmile:
    其 它都解決了,請問以下兩個值要用什么函數才能抓到iManufacturer:        Kingston
    iProduct:            DataTraveler 2.0