delphi – 始终检测可移动设备的最佳方式
在我之前的问题“如何找到闪存设备的唯一序列号?”我最终要求找到驱动器号的方法.那个问题解决了.
但是,我的初步问题尚未得到解答.我希望能够将可移动设备(USB驱动器,SD卡,(外部硬盘驱动器?)等)分开,并且在重新连接时始终能够再次识别它们.这也应该可以在任何其他计算机上使用.幸运的是,我不关心正在格式化的驱动器(如果/何时,它们在我的程序中被视为新驱动器),那么我可以使用分区和卷ID作为我识别的一部分吗?我问这是因为PNPDeviceID不是唯一的.我发现它取决于阅读它的硬件,见下图: alt text http://i48.tinypic.com/28uofmc.png alt text http://i46.tinypic.com/rk5tv6.jpg 因此,我正在搜索的是一种使用以下方法检测和识别任何计算机上的任何可移动设备的方法:Win32_DiskDrive,Win32_DiskPartition,Win32_LogicalDisk.我感谢原始代码RRUZ: program GetWMI_USBConnectedInfo; {$APPTYPE CONSOLE} uses Windows,Classes,ActiveX,Variants,SysUtils,WbemScripting_TLB in '....DocumentsRAD Studio5.0ImportsWbemScripting_TLB.pas'; procedure GetUSBDiskDriveInfo; var WMIServices : ISWbemServices; Root,a,b : ISWbemObjectSet; Item,Item2 : Variant; i,ii,iii,iiii: Integer; start,stop,freq:Int64; begin QueryPerformanceFrequency(freq); QueryPerformanceCounter(start); WMIServices := CoSWbemLocator.Create.ConnectServer('.','rootcimv2','',nil); Root := WMIServices.ExecQuery('Select * From Win32_DiskDrive','WQL',nil); for i := 0 to Root.Count - 1 do begin Item := Root.ItemIndex(i); for ii := VarArrayLowBound(Item.Capabilities,1) to VarArrayHighBound(Item.Capabilities,1) do if (Item.Capabilities[ii] = 7) then begin Writeln('Caption '+VarToStr(Item.Caption)); Writeln('Name '+VarToStr(Item.Name)); Writeln('DeviceID '+VarToStr(Item.DeviceID)); Writeln('Partitions '+VarToStr(Item.Partitions)); Writeln('PNPDeviceID '+VarToStr(Item.PNPDeviceID)); Writeln('SerialNumber '+VarToStr(Item.SerialNumber)); Writeln('Signature '+VarToStr(Item.Signature)); a := WMIServices.ExecQuery('ASSOCIATORS OF {Win32_DiskDrive.DeviceID=''' + VarToStr(Item.DeviceID) + '''} WHERE AssocClass = Win32_DiskDriveToDiskPartition',nil); for iiii := 0 to a.Count - 1 do begin b := WMIServices.ExecQuery('ASSOCIATORS OF {Win32_DiskPartition.DeviceID=''' + VarToStr(Variant(a.ItemIndex(iiii)).DeviceID) + '''} WHERE AssocClass = Win32_LogicalDiskToPartition',nil); for iii := 0 to b.Count - 1 do begin Item2 := b.ItemIndex(iii); Writeln('Drive = ' + Item2.Caption); end; end; Writeln; Writeln; end; end; QueryPerformanceCounter(stop); if (freq > 0) then Writeln('Time took: ' + FloatToStr((stop-start) / freq)) else Writeln('Unable to measure time!'); end; begin try CoInitialize(nil); GetUSBDiskDriveInfo; Readln; CoUninitialize; except on E:Exception do Begin CoUninitialize; Writeln(E.Classname,': ',E.Message); Readln; End; end; end. 编辑 最后编辑 解: >使用程序可识别的唯一ID保存驱动器上的隐藏文件(与本地数据库比较). 解决方法
您应该能够使用与磁盘总大小和卷名称配对的卷ID来确定磁盘是否相同,尽管卷ID本身就足够了.
唯一的问题可能是大规模生产的媒体.在某些情况下,卷ID,磁盘大小和卷名称将匹配所有副本. 编辑我不确定你是否可以绝对解决所有设备的问题.来自每个供应商的硬件是不同的,并且规范是用于解释的,这就是为什么某些设备的序列号为空的原因,而有些则不是.您唯一的希望是自己提供硬件或要求以可预测的方式运行的特定硬件. 如果您可以写入设备,并且用户可以接受,则可以创建包含唯一标识符(例如guid)的只读系统隐藏文件,并使用该文件进行比较.这样只会阻止使用默认设置运行Windows的普通用户(隐藏系统文件,并且没有选中显示隐藏文件)复制文件,并且在您的检查中也包括卷ID,磁盘大小和卷名称将坚持它只允许镜像设备.它可能无法获得所有实例,但它可能已经足够了. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |