Windows 获取特定驱动器的GUID

Windows 获取特定驱动器的GUID,windows,delphi,winapi,Windows,Delphi,Winapi,我想找出特定驱动器号的驱动器GUID。 我有以下代码: Function GetVolumeNameForVolumeMountPoint(lpszVolumeMountPoint: LPCTSTR; lpszVolumeName: LPTSTR; cchBufferLength: DWORD): BOOL; stdcall; external 'kernel32.dll' name 'GetVolumeNameForVolumeMountPointW'; procedure TForm1

我想找出特定驱动器号的驱动器GUID。 我有以下代码:

Function GetVolumeNameForVolumeMountPoint(lpszVolumeMountPoint: LPCTSTR; lpszVolumeName: LPTSTR; cchBufferLength: DWORD): BOOL; stdcall;
  external 'kernel32.dll' name 'GetVolumeNameForVolumeMountPointW';

procedure TForm1.Button1Click(Sender: TObject);
var
  Buffer: array[0..50] of AnsiChar;
begin
  if GetVolumeNameForVolumeMountPoint('C:\', Buffer, SizeOf(Buffer)) then
  begin
    showmessage(buffer); // Expected: "\\?\Volume{deadbeef-895e-4a1d-9d64-9b82fa068d76}\"
  end
  else RaiseLastOSError; // Actual: ERROR_INVALID_NAME (123).
end;

我收到错误
错误\u无效\u名称(123)
,但我不知道原因。我做错了什么?

您调用的是Unicode版本的函数,但传递的是ANSI文本。因此,您传递的第一个参数被错误编码,因此出现错误消息

此程序演示了如何执行此操作:

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows;

function GetVolumeNameForVolumeMountPointA(lpszVolumeMountPoint: PAnsiChar;
  lpszVolumeName: PAnsiChar; cchBufferLength: DWORD): BOOL; stdcall;
  external 'kernel32.dll';

procedure Main;
var
  Buffer: array [0 .. 49] of AnsiChar;
begin
  Win32Check(GetVolumeNameForVolumeMountPointA('C:\', Buffer, Length(Buffer)));
  Writeln(Buffer);
end;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.
很明显,您使用的是Delphi的前Unicode版本(否则您的程序将无法编译),因此我在上面为您提供了ANSI代码。如果您曾经升级到Delphi的Unicode版本,那么您可以这样编写:

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows;

function GetVolumeNameForVolumeMountPointW(lpszVolumeMountPoint: PWideChar;
  lpszVolumeName: PWideChar; cchBufferLength: DWORD): BOOL; stdcall;
  external 'kernel32.dll';

procedure Main;
var
  Buffer: array [0 .. 49] of WideChar;
begin
  Win32Check(GetVolumeNameForVolumeMountPointW('C:\', Buffer, Length(Buffer)));
  Writeln(Buffer);
end;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.
或者,如果您想要在所有版本的Delphi中都能运行的代码,可以执行以下操作:

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows;

const
  Win32ImportSuffix = {$IFDEF Unicode}'W'{$ELSE}'A'{$ENDIF};

function GetVolumeNameForVolumeMountPointA(lpszVolumeMountPoint: PAnsiChar;
  lpszVolumeName: PAnsiChar; cchBufferLength: DWORD): BOOL; stdcall;
  external 'kernel32.dll';
function GetVolumeNameForVolumeMountPointW(lpszVolumeMountPoint: PWideChar;
  lpszVolumeName: PWideChar; cchBufferLength: DWORD): BOOL; stdcall;
  external 'kernel32.dll';
function GetVolumeNameForVolumeMountPoint(lpszVolumeMountPoint: PChar;
  lpszVolumeName: PChar; cchBufferLength: DWORD): BOOL; stdcall;
  external 'kernel32.dll' name 'GetVolumeNameForVolumeMountPoint' + Win32ImportSuffix;

procedure Main;
var
  Buffer: array [0 .. 49] of Char;
begin
  Win32Check(GetVolumeNameForVolumeMountPoint('C:\', Buffer, Length(Buffer)));
  Writeln(Buffer);
end;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.