Delphi工具中如何排除被GetDriveType识别为DRIVE_FIXED的Google Drive?
如何在Delphi中准确排除Google Drive这类伪本地固定驱动器?
我用Delphi开发了一款硬盘剩余空间监控工具,原本通过GetDriveType函数检测驱动器类型,但Google Drive会被误识别为DRIVE_FIXED类型。目前我是通过检测驱动器名称是否包含“google”来排除它,但这个方法不够简洁可靠,想找更优的识别排除方式。
现有代码示例
procedure TFormSpace.CreaLabels; var Type, i, n: Word; LblDummy: TLabel; Candidate: string; begin Max:=0; i:=1; repeat Candidate:=chr(ord('c')+i-1) + ':\'; Type:=GetDriveType(pchar(Candidate)); if (Tipo=DRIVE_FIXED) then begin //Do something end; i:=i+1; until (i=MaxItems); end;
环境说明
c:\ -> 1TB SSD(真实物理驱动器) d:\ -> 2TB SSD(真实物理驱动器) f:\ -> 映射网络驱动器 g:\ -> Google Drive(同步到本地的虚拟驱动器)
当前代码会返回 C:\ D:\ G:\,预期仅返回真实物理驱动器 C:\ D:\。
解决方案:通过WMI关联物理磁盘与逻辑驱动器
这个方法直接通过Windows管理规范(WMI)查询逻辑驱动器对应的物理磁盘信息,能准确区分真实物理固定驱动器和Google Drive这类虚拟驱动器,不受卷名修改或本地化影响。
实现辅助函数
uses SysUtils, Classes, WbemScripting_TLB; function IsPhysicalFixedDrive(const DriveLetter: Char): Boolean; var WMIService: ISWbemServices; DiskDrives: ISWbemObjectSet; DiskDrive: ISWbemObject; Partitions: ISWbemObjectSet; Partition: ISWbemObject; LogicalDisks: ISWbemObjectSet; LogicalDisk: ISWbemObject; TargetDrive: string; begin Result := False; TargetDrive := UpperCase(DriveLetter) + ':'; // 连接本地WMI服务 WMIService := CoSWbemLocator.Create.ConnectServer('.', 'root\cimv2', '', '', '', '', 0, nil); // 查询所有物理固定硬盘 DiskDrives := WMIService.ExecQuery( 'SELECT * FROM Win32_DiskDrive WHERE MediaType="Fixed hard disk media"', 'WQL', wbemFlagForwardOnly or wbemFlagReturnImmediately, nil ); for DiskDrive in DiskDrives do begin // 获取当前硬盘关联的分区 Partitions := DiskDrive.Associators_( 'Win32_DiskDriveToDiskPartition', '', '', '', '', '', 0, nil ); for Partition in Partitions do begin // 获取当前分区关联的逻辑驱动器 LogicalDisks := Partition.Associators_( 'Win32_LogicalDiskToPartition', '', '', '', '', '', 0, nil ); for LogicalDisk in LogicalDisks do begin if SameText(LogicalDisk.Properties_.Item('DeviceID', 0).Value, TargetDrive) then begin Result := True; Exit; end; end; end; end; end;
修改原有代码
将原有判断逻辑替换为同时检查驱动器类型和是否为物理磁盘:
procedure TFormSpace.CreaLabels; var DriveType: Word; i: Word; Candidate: string; DriveLetter: Char; begin Max := 0; i := 1; repeat DriveLetter := Chr(Ord('C') + i - 1); Candidate := DriveLetter + ':\'; DriveType := GetDriveType(PChar(Candidate)); // 仅处理真实物理固定驱动器 if (DriveType = DRIVE_FIXED) and IsPhysicalFixedDrive(DriveLetter) then begin // 执行你的业务逻辑 end; Inc(i); until (i = MaxItems); end;
备选方案:通过卷信息识别Google Drive
如果不想引入WMI依赖,也可以通过GetVolumeInformation读取卷名特征来排除,这种方法更轻量但可靠性稍低(依赖卷名包含关键词):
function IsGoogleDrive(const DrivePath: string): Boolean; var VolumeName: array[0..MAX_PATH] of Char; begin Result := False; if GetVolumeInformation(PChar(DrivePath), VolumeName, SizeOf(VolumeName), nil, nil, nil, nil, 0) then begin Result := Pos('GOOGLE', UpperCase(VolumeName)) > 0; end; end;
使用时修改判断条件:
if (DriveType = DRIVE_FIXED) and not IsGoogleDrive(Candidate) then begin // 执行你的业务逻辑 end;
内容的提问来源于stack exchange,提问作者SullyPanda76cl
相关产品推荐
相关产品推荐

