Как найти уникальный серийный номер флеш-устройства?
Я нашел несколько фрагментов и файлов.pas, которые могут определить, когда USB-накопители вставлены и извлечены. Некоторые дают всевозможную полезную информацию, однако мне нужен уникальный серийный номер устройства, а не серийный номер тома.
Мой текущий файл.pas (который я не помню, где я нашел) также, кажется, обнаруживает SD-карты (которые мне нравятся). Если вы хотите посмотреть, вы можете найти его здесь (он только возвращает номер диска и вставлен / удален):
unit UsbDetector;
interface
uses Classes;
type
TUsbDriveChanged = procedure (Sender: TObject; Drive: string; Attached: boolean) of object;
procedure StartUsbDetector(NotifyProc: TUsbDriveChanged);
procedure StopUsbDetector;
implementation
uses Windows, Messages, Forms, SysUtils;
type
TUSBDetector = class(TObject)
private
fUsbDriveChanged: TUsbDriveChanged;
protected
procedure DeviceChanged(Msg: UINT; wParam, lParam: Longint);
procedure DoUsbDriveChanged(Drive: string; Attached: Boolean); dynamic;
public
constructor Create(NotifyProc: TUsbDriveChanged);
destructor Destroy; override;
property OnUsbDriveChanged: TUsbDriveChanged read fUsbDriveChanged;
end;
var mUSBDetector: TUSBDetector;
procedure StartUsbDetector(NotifyProc: TUsbDriveChanged);
begin
if not Assigned(mUsbDetector) then
mUsbDetector := TUsbDetector.Create(NotifyProc);
end;
procedure StopUsbDetector;
begin
FreeAndNil(mUsbDetector);
end;
{----------------------------------------------------------------------------}
// Device constants
const
DBT_DEVICEARRIVAL = $00008000;
DBT_DEVICEREMOVECOMPLETE = $00008004;
DBT_DEVTYP_VOLUME = $00000002;
// Device structs
type
_DEV_BROADCAST_HDR = packed record
dbch_size: DWORD;
dbch_devicetype: DWORD;
dbch_reserved: DWORD;
end;
DEV_BROADCAST_HDR = _DEV_BROADCAST_HDR;
TDevBroadcastHeader = DEV_BROADCAST_HDR;
PDevBroadcastHeader = ^TDevBroadcastHeader;
type
_DEV_BROADCAST_VOLUME = packed record
dbch_size: DWORD;
dbch_devicetype: DWORD;
dbch_reserved: DWORD;
dbcv_unitmask: DWORD;
dbcv_flags: WORD;
end;
DEV_BROADCAST_VOLUME = _DEV_BROADCAST_VOLUME;
TDevBroadcastVolume = DEV_BROADCAST_VOLUME;
PDevBroadcastVolume = ^TDevBroadcastVolume;
var
fPrevWndProc: TFNWndProc = nil;
function UsbWndProc(hWnd: HWND; Msg: UINT; wParam, lParam: Longint): Longint; stdcall;
begin
Result := CallWindowProc(fPrevWndProc, hWnd, Msg, wParam, lParam);
if (Msg = WM_DEVICECHANGE) and (mUsbDetector <> nil) then
mUsbDetector.DeviceChanged(Msg, wParam, lParam);
end;
constructor TUSBDetector.Create(NotifyProc: TUsbDriveChanged);
begin
inherited Create;
fUsbDriveChanged := NotifyProc;
if not Assigned(fPrevWndProc) then
begin
fPrevWndProc := TFNWndProc(GetWindowLong(Application.Handle, GWL_WNDPROC));
SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(@UsbWndProc));
end;
end;
destructor TUSBDetector.Destroy;
begin
//SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(@fPrevWndProc));
inherited Destroy;
end;
procedure TUSBDetector.DeviceChanged(Msg: UINT; wParam, lParam: LongInt);
var
lpdbhHeader: PDevBroadcastHeader;
lpdbvData: PDevBroadcastVolume;
dwIndex: Integer;
lpszDrive: string;
begin
// Get the device notification header
lpdbhHeader := PDevBroadcastHeader(lParam);
// Handle the message
lpszDrive := '';
case WParam of
DBT_DEVICEARRIVAL: {a USB drive was connected}
begin
if lpdbhHeader^.dbch_devicetype = DBT_DEVTYP_VOLUME then
begin
lpdbvData := PDevBroadcastVolume(lParam);
for dwIndex := 0 to 25 do
begin
if (lpdbvData^.dbcv_unitmask shr dwIndex) = 1 then
begin
lpszDrive := lpszDrive + Chr(65 + dwIndex) + ':\';
break;
end;
end;
DoUsbDriveChanged(lpszDrive, True);
end;
end;
DBT_DEVICEREMOVECOMPLETE: {a USB drive was removed}
begin
if lpdbhHeader^.dbch_devicetype = DBT_DEVTYP_VOLUME then
begin
lpdbvData := PDevBroadcastVolume(lParam);
for dwIndex := 0 to 25 do
begin
if (lpdbvData^.dbcv_unitmask shr dwIndex) = 1 then
begin
lpszDrive := lpszDrive + Chr(65 + dwIndex) + ':\';
break;
end;
end;
DoUsbDriveChanged(lpszDrive, False);
end;
end;
end;
end;
procedure TUSBDetector.DoUsbDriveChanged(Drive: string; Attached: Boolean);
begin
if Assigned(fUsbDriveChanged) then
fUsbDriveChanged(Self, Drive, Attached);
end;
end.
PS Подсветка кода не удалась.
В общем; Когда съемный вставлен / удален, получите букву диска и его уникальный серийный номер. Может быть, объединить уже приведенный код с WMI-вызовом "где Index = found_index".
**** РЕДАКТИРОВАТЬ!**** Я удалил пункт "где" в коде, заданном RRUZ. Я наконец узнал, как обращаться с массивами, поэтому я использую это, чтобы найти Capabilities[i]=7, чтобы получить все съемные носители. Теперь мне просто нужно соединить этот код с приведенным выше кодом. Я думаю об использовании индекса, но я не знаю, как использовать GetDrive MapInfo. Если бы вы могли предоставить мне пример получения буквы диска, мой вопрос решен.
1 ответ
Вы можете использовать библиотеку WMI от Magenta Systems, которая берет на себя большую часть боли при использовании запросов WMI. Бесплатная загрузка включает в себя исходный код и пример проекта, который позволяет вам играть с API и выполнять запросы к содержанию вашего сердца. Вы захотите сохранить ссылку на официальную документацию Microsoft API, которая поможет вам с каким запросом выполнить, чтобы получить какую информацию... вы заинтересованы в запросах классов с использованием SQL-подобных синтаксических запросов.
Например, выполнение запроса
SELECT * FROM Win32_DiskDrive Where InterfaceType = 'USB'
возвращает обширную информацию обо всех USB-устройствах, подключенных в данный момент к машине. Затем вы можете использовать PNPDeviceID в качестве уникального идентификатора.
РЕДАКТИРОВАТЬ, проверяя единственное USB-устройство, которое было у меня под рукой, вернуло аппаратный серийный номер "u", но очень длинный и корректно выглядящий PNPDeviceID, который, как оказалось, содержал серийный номер, поэтому я предложил это поле.
РЕДАКТИРОВАТЬ Вы можете получить букву диска, выполнив запрос к Win32_LogicalDisk
Вы также можете запросить Win32_DiskDriveToDiskPartition
который содержит отображение между Win32_DiskDrive
а также Win32_DiskPartition
, в заключение Win32_LogicalDiskToPartition
затем сопоставляет логический диск с разделом, который, в свою очередь, дает вам возможность связать физический USB-диск с определенной буквой диска.