How can I use GetVolumeInformation in Inno Setup?

巧了我就是萌 提交于 2019-12-03 08:13:23

Inno-Setup code::

[Code]
function GetVolumeInformation(
  lpRootPathName: PChar;
  lpVolumeNameBuffer: PChar;
  nVolumeNameSize: DWORD;
  var lpVolumeSerialNumber: DWORD;
  var lpMaximumComponentLength: DWORD;
  var lpFileSystemFlags: DWORD;
  lpFileSystemNameBuffer: PChar;
  nFileSystemNameSize: DWORD
  ): BOOL;
  external 'GetVolumeInformationA@kernel32.dll stdcall';


function LoWord(dw: DWORD): WORD;
begin
  Result := WORD(dw);
end;

function HiWord(dw: DWORD): WORD;
begin
  Result := WORD((dw shr 16) and $FFFF);
end;

function WordToHex(w: WORD): string;
begin
  Result := Format('%.4x', [w]);
end;

function FindVolumeSerial(const Drive: string): string;
var
  FileSystemFlags: DWORD;
  VolumeSerialNumber: DWORD;
  MaximumComponentLength: DWORD;
begin
  Result := '';
  // Note on passing PChars using RemObjects Pascal Script:
  // '' pass a nil PChar  
  // #0 pass an empty PChar    
  if GetVolumeInformation(
    PChar(Drive), 
    '', // nil
    0,
    VolumeSerialNumber,
    MaximumComponentLength,
    FileSystemFlags,
    '', // nil
    0)
  then
    Result := WordToHex(HiWord(VolumeSerialNumber)) + '-' + WordToHex(LoWord(VolumeSerialNumber));
end;

function InitializeSetup(): Boolean;
begin
  MsgBox(FindVolumeSerial('c:\'), mbInformation, mb_Ok);
end;

Tested with Inno-setup version 5.2.3
In Unicode versions of Inno-Setup replace PChar with PAnsiChar

Since the InnoSetup doesn't support pointers you will have to create the external library for the call of the GetVolumeInformation function. The following code samples should work for all combinations of the Delphi and InnoSetup (from the Unicode support point of view).

Here's the Delphi library code:

library VolumeInformation;

uses
  Types, Classes, SysUtils, Windows;

var
  SerialNumber: AnsiString;

function GetVolumeSerial(Drive: PAnsiChar): PAnsiChar; stdcall;
var
  FileSystemFlags: DWORD;
  VolumeSerialNumber: DWORD;
  MaximumComponentLength: DWORD;
begin
  SerialNumber := '';
  GetVolumeInformationA(Drive, nil, 0, @VolumeSerialNumber,
    MaximumComponentLength, FileSystemFlags, nil, 0);
  SerialNumber := IntToHex(HiWord(VolumeSerialNumber), 4) + ' - ' +
    IntToHex(LoWord(VolumeSerialNumber), 4);
  Result := PAnsiChar(SerialNumber);
end;

exports
  GetVolumeSerial;

end.

And here's the InnoSetup code:

[Files]
Source: "VolumeInformation.dll"; Flags: dontcopy

[Code]

function GetVolumeSerial(Drive: PAnsiChar): PAnsiChar;
  external 'GetVolumeSerial@files:VolumeInformation.dll stdcall setuponly';

procedure ButtonOnClick(Sender: TObject);
var
  S: string;
begin
  S := GetVolumeSerial('c:\');
  MsgBox(S, mbInformation, mb_Ok);
end;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!