USB 플래시 드라이브를 삽입하고 제거 할 때 감지 할 수있는 몇 가지 코드 및 .pas 파일을 발견했습니다. 일부는 모든 종류의 좋은 정보를 제공하지만 필요한 것은 장치의 고유 한 일련 번호가 아니라 볼륨의 일련 번호입니다.플래시 장치의 고유 일련 번호를 찾는 방법은 무엇입니까?
내 현재 .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.
P.S. 코드 강조 표시가 실패했습니다.
모두 모두; 이동식을 삽입하거나 제거 할 때 드라이브 문자와 고유 한 일련 번호를 가져옵니다. 이미 주어진 코드를 WMI 호출 "where Index = found_index"와 결합 할 수 있습니다.
**** EDIT! **** RRUZ가 제공 한 코드에서 "where"절이 제거되었습니다. 마침내 배열을 처리하는 방법을 알아 냈으므로 모든 이동식 미디어를 가져 오기 위해 Capabilities [i] = 7을 찾는 데 사용했습니다. 이제이 코드를 위의 코드와 연결해야합니다. 인덱스를 사용하여 생각하고 있지만 GetDrive MapInfo 사용하는 방법을 모르겠습니다. 당신이 드라이브 편지를 얻는 것에 대한 예제를 제게 줄 수 있다면, 제 질문이 풀립니다.
@ 대니얼,이 질문에 체크하십시오. http://stackoverflow.com/questions/1687239/getting-connected-usb-info-with-delphi-on-vista – RRUZ
그래,하지만 내가 원하는 걸 잊어 버렸어. 표준 방법 (있는 경우). 나는 대안이 없다면 이것을 사용할 수 있다고 생각한다. –
좋습니다. 작동합니다. 그러나 USB 스틱 만 감지합니다. 그리고 이미 기존 유닛과 연결할 수있는 방법이 없습니다. –