检测可移动驱动器(例如USB闪存驱动器)C / C ++

如何检测可移动磁盘驱动器何时(dis)连接到系统? 如何获取挂载路径(对于Linux)和驱动器号(对于Windows)?

编辑:有没有办法检测当前连接的设备?

对于Windows,API RegisterDeviceNotification将在您添加USB设备时通知您。 有关卷的信息在DEV_BROADCAST_VOLUME结构中给出。 dbcv_unitmask给出驱动器号。

您可以从shell获取更改通知(针对驱动器添加/删除)。 您可以使用此Delphi代码作为文档使用:

 unit UnitChangeNotify; interface uses Windows, Messages, SysUtils, Classes, ShlObj, Types; type SHChangeNotifyEntry = record pidlPath : PItemIDList; bWatchSubtree : Boolean; end; TChangeEventType = ( cnAssocchanged, cnAttributes, cnCreate, cnDelete, cnDriveAdd, cnDriveAddGui, cnDriveRemoved, cnMediaInserted, cnMediaRemoved, cnMkdir, cnNetShare, cnNetUnshare, cnRenameFolder, cnRenameItem, cnRmdir, cnServerDisconnect, cnUpdateDir, cnUpdateImage, cnUpdateItem ); TChangeNotifyEvent = procedure( Sender: TObject; Event: TChangeEventType; const Paths: TStringDynArray ) of object; TChangeNotify = class( TComponent ) private FHWnd: HWND; FRegID: THandle; FEntry: SHChangeNotifyEntry; FOnChange: TChangeNotifyEvent; function GetActive (): Boolean; procedure SetActive ( const Value: Boolean ); procedure WndProc ( var Msg: TMessage ); procedure DoEvent ( Event: TChangeEventType; const Paths: TStringDynArray ); virtual; public constructor Create ( Aowner: TComponent ); override; destructor Destroy; override; property Active: Boolean read GetActive write SetActive; property OnChange: TChangeNotifyEvent read FOnChange write FOnChange; end; const SHCNF_ACCEPT_INTERRUPTS = $0001; SHCNF_ACCEPT_NON_INTERRUPTS = $0002; SHCNF_NO_PROXY = $8000; function SHChangeNotifyRegister( hWnd: HWND; fSources: Integer; wEventMask: DWORD; uMsg: UINT; cItems: integer; const Items: SHChangeNotifyEntry ): THandle; stdcall; function SHChangeNotifyDeregister( hRegID: THandle ) : BOOL; stdcall; function SHILCreateFromPath( Path: Pointer; PIDL: PItemIDList; var Attributes: ULONG ): HResult; stdcall; implementation const Shell32DLL = 'shell32.dll'; function SHChangeNotifyRegister; external Shell32DLL index 2; function SHChangeNotifyDeregister; external Shell32DLL index 4; function SHILCreateFromPath; external Shell32DLL index 28; { TChangeNotify } constructor TChangeNotify.Create( Aowner: TComponent ); begin inherited Create( AOwner ); end; destructor TChangeNotify.Destroy; begin Active := False; inherited Destroy; end; procedure TChangeNotify.DoEvent( Event: TChangeEventType; const Paths: TStringDynArray ); begin if Assigned( FOnChange ) then FOnChange( Self, Event, Paths ); end; function TChangeNotify.GetActive(): Boolean; begin Result := FHWnd <> 0; end; procedure TChangeNotify.SetActive( const Value: Boolean ); begin if Value = GetActive() then Exit; if Value then begin FHWnd := AllocateHWnd( WndProc ); FEntry.pidlPath := nil; FEntry.bWatchSubtree := True; FRegID := SHChangeNotifyRegister( FHWnd, SHCNF_ACCEPT_INTERRUPTS or SHCNF_ACCEPT_NON_INTERRUPTS, SHCNE_ALLEVENTS, WM_USER, 1, FEntry ); if FRegID = 0 then begin DeallocateHWnd( FHWnd ); FHWnd := 0; RaiseLastOSError(); end; end else begin SHChangeNotifyDeregister( FRegID ); FRegID := 0; DeallocateHWnd( FHWnd ); FHWnd := 0; end; end; procedure TChangeNotify.WndProc( var Msg: TMessage ); type PPITEMIDLIST = ^PITEMIDLIST; var Event: TChangeEventType; i: Integer; Paths: TStringDynArray; P: PPITEMIDLIST; const EventBits: array [ TChangeEventType ] of DWORD = ( SHCNE_ASSOCCHANGED, SHCNE_ATTRIBUTES, SHCNE_CREATE, SHCNE_DELETE, SHCNE_DRIVEADD, SHCNE_DRIVEADDGUI, SHCNE_DRIVEREMOVED, SHCNE_MEDIAINSERTED, SHCNE_MEDIAREMOVED, SHCNE_MKDIR, SHCNE_NETSHARE, SHCNE_NETUNSHARE, SHCNE_RENAMEFOLDER, SHCNE_RENAMEITEM, SHCNE_RMDIR, SHCNE_SERVERDISCONNECT, SHCNE_UPDATEDIR, SHCNE_UPDATEIMAGE, SHCNE_UPDATEITEM ); EventPIDLCount: array [ TChangeEventType ] of Integer = ( 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1 ); begin case Msg.Msg of WM_USER: begin // lParam = eventmask // wParam = array of PIDLs with for Event := Low( Event ) to High( Event ) do begin if EventBits[ Event ] and msg.LParam = EventBits[ Event ] then begin SetLength( Paths, EventPIDLCount[ Event ] ); P := PPITEMIDLIST( Msg.WParam ); for i := 0 to High( Paths ) do begin SetLength( Paths[ i ], MAX_PATH ); if not SHGetPathFromIDList( P^, PChar( Paths[ i ] ) ) then Paths[ i ] := '' else Paths[ i ] := PChar( Paths[ i ] ); Inc( P ); end; DoEvent( Event, Paths ); Break; end; end; end; end; DefaultHandler( Msg ); end; end.