delphi如何获取最后插入的U盘盘符?
在写一个U盘应用,请教高手如何识别最后插入的U盘盘符?例如我的电脑插入U盘出现的第一个盘符是F1、插入第一个U盘时,程序读出来此U盘的盘符F2、不拔出第一个U盘,插入第2...
在写一个U盘应用,请教高手如何识别最后插入的U盘盘符?
例如我的电脑插入U盘出现的第一个盘符是F
1、插入第一个U盘时,程序读出来此U盘的盘符F
2、不拔出第一个U盘,插入第2个U盘时,读出来盘符G 展开
例如我的电脑插入U盘出现的第一个盘符是F
1、插入第一个U盘时,程序读出来此U盘的盘符F
2、不拔出第一个U盘,插入第2个U盘时,读出来盘符G 展开
1个回答
展开全部
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,registry;
type
TForm1 = class(TForm)
Label1: TLabel;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure checkdevice(var MSG:Tmessage); message WM_DEVICECHANGE;
end;
var
Form1: TForm1;
flag:boolean;
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;
implementation
{$R *.dfm}
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(const 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;
try
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 Delete(USBPath, 1, Pos('#', USBPath));
PID := Copy(USBPath, Pos('#', USBPath) + 1, Length(USBPath));
PID := Copy(PID, 1, Pos('#{', PID) - 1);
PID := UpperCase(StringReplace(PID, '&', '', [rfReplaceAll]));
Result := True; Break; end; Reg.CloseKey; Inc(Devn); end;
FreeMem(FunctionClassDeviceData); end; end;
until not Success;
SetupDiDestroyDeviceInfoList(USBHandle);
finally Reg.Free; end; end;
procedure Tform1.checkdevice(var msg: TMessage);
const
DBT_DEVICEARRIVAL = $8000;
DBT_DEVICEREMOVECOMPLETE = $8004;
DBT_DEVNODES_CHANGED = $0007;
var i,j:longint; ssss,idd:string;
begin
if flag then exit;
case msg.WParam of
DBT_DEVICEARRIVAL:begin
for i:=1 to 26 do begin
if directoryexists(chr(64+i)+':\') and (GetDriveType(PChar(chr(64+i)+':\')) = DRIVE_REMOVABLE)
then begin
showmessage('');
end;
end;
end;//增加了新硬件
DBT_DEVICEREMOVECOMPLETE:begin
ShowMessage('') ;//移除硬件
end;
DBT_DEVNODES_CHANGED:
begin
showmessage('');
end;
end;
end;
end.
以上代码在增加硬件时检测有多少个盘符,将新增的记录下来,移除硬件时将记录删去就好了
更多追问追答
追问
谢谢您的答复。但是您给的代码跟我自己的代码差不多,只能识别插入了几个U盘,但是不知道哪个是最后插入的。并不是盘符越大就是越后面插入的。
追答
不是,一开始队列为空,每次arrival就检测多了哪些,并且将新增的进队列,下一次arrival就看队列里什么是没有的而实际上是有的,那么这些就是新增的,同理,remove就删掉队列中相应元素
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询