USB记忆棒有两个分区 - 一个只读,另一个读写。
我的程序从只读分区运行。
两个分区的卷标由制造商确定: MYDISK-RO和MYDISK-RW
在Windows中插入时,每个分区(卷)都会获得不同的驱动器号。根据配置,这些驱动器号在不同的计算机上是不同的。已分配给磁盘驱动器的驱动器号的数量。
我的问题是:
使用卷标找到程序找到读写分区的驱动器号的最佳(最有效)方法是什么?
它需要在Windows XP及更高版本上运行。
我没有枚举所有的驱动器号并将卷标与我们需要的卷标进行比较,而是理想地寻找对Windows的单个函数调用。例如:
GetDriveLetterByVolumeName(AVolumeLabel:String);
或
GetVolumeInformation(AVolumeLabel:String);
是否有这样的功能或枚举驱动器号并将每个卷标比较唯一的解决方案?
TIA。
答案 0 :(得分:1)
Procedure TfMain.GetDiskDrives();
var
r: LongWord;
Drives: array[0..128] of char;
pDrive: pchar;
begin
Result := '';
r := GetLogicalDriveStrings(sizeof(Drives), Drives);
if r = 0 then exit;
if r > sizeof(Drives) then
raise Exception.Create(SysErrorMessage(ERROR_OUTOFMEMORY));
pDrive := Drives; // Point to the first drive
while pDrive^ <> #0 do begin
if GetDriveType(pDrive) = DRIVE_REMOVABLE then begin
cDrive.Items.Add(pDrive);
end;
inc(pDrive, 4); // Point to the next drive
end;
if cDrive.Items.Count=1 then cDrive.ItemIndex:=0;
end;
之后,您可以使用以下函数获取卷名
function GetVolumeName(DriveLetter: Char): string;
var
dummy: DWORD;
buffer: array[0..MAX_PATH] of Char;
oldmode: LongInt;
begin
oldmode := SetErrorMode(SEM_FAILCRITICALERRORS);
try
GetVolumeInformation(PChar(DriveLetter + ':\'),
buffer,
SizeOf(buffer),
nil,
dummy,
dummy,
nil,
0);
Result := StrPas(buffer);
finally
SetErrorMode(oldmode);
end;
end;
答案 1 :(得分:-1)
我发布的代码改编自Gianluca Colombo的答案:
在Windows 7 x64上测试并使用Delphi XE2 Update 4.1。
unit uDiskUtils;
interface
uses Windows, Classes, SysUtils;
Procedure GetDiskDrives(var ADriveList: TStrings);
function GetVolumeName(const ADriveLetter: Char): string;
function FindDiskDriveByVolumeName(const AVolumeName: String): Char;
implementation
Procedure GetDiskDrives(var ADriveList: TStrings);
var
r: LongWord;
Drives: array [0 .. 128] of Char;
pDrive: pchar;
begin
ADriveList.Clear;
r := GetLogicalDriveStrings(sizeof(Drives), Drives);
if r = 0 then
exit;
if r > sizeof(Drives) then
raise Exception.Create(SysErrorMessage(ERROR_OUTOFMEMORY));
pDrive := Drives; // Point to the first drive
while pDrive^ <> #0 do
begin
if GetDriveType(pDrive) = DRIVE_REMOVABLE then
begin
ADriveList.Add(pDrive);
end;
inc(pDrive, 4); // Point to the next drive
end;
end;
function GetVolumeName(const ADriveLetter: Char): string;
var
dummy: DWORD;
buffer: array [0 .. MAX_PATH] of Char;
oldmode: LongInt;
begin
oldmode := SetErrorMode(SEM_FAILCRITICALERRORS);
try
GetVolumeInformation(pchar(ADriveLetter + ':\'), buffer, sizeof(buffer), nil, dummy, dummy, nil, 0);
Result := StrPas(buffer);
finally
SetErrorMode(oldmode);
end;
end;
function FindDiskDriveByVolumeName(const AVolumeName: String): Char;
var
dl: TStringList;
c: Integer;
begin
Result := ' ';
dl := TStringList.Create;
try
GetDiskDrives(TStrings(dl));
for c := 0 to dl.Count - 1 do
if (AVolumeName = GetVolumeName(dl[c][1])) then
Result := dl[c][1];
finally
dl.Free;
end;
end;
end.