Как я могу использовать GetVolumeInformation в Inno Setup? - PullRequest
7 голосов
/ 14 февраля 2012

Мне нужно получить серийный номер тома для буквы диска во время установки, созданной с помощью Inno Setup.Я знаю, что функции DLL можно импортировать в Inno, но я довольно новичок в этом, и у меня возникают некоторые проблемы с его работой.Я знаю, что функция GetVolumeInformation в kernel32 может делать то, что мне нужно.Может кто-нибудь показать мне, как импортировать и использовать эту функцию в сценарии Inno для получения серийного номера тома?

Спасибо!

Ответы [ 2 ]

8 голосов
/ 16 февраля 2012

Код Inno-Setup ::

[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;

Протестировано с Inno-setup версии 5.2.3
В Unicode-версиях Inno-Setup заменить PChar на PAnsiChar

4 голосов
/ 14 февраля 2012

Поскольку InnoSetup не поддерживает указатели, вам нужно будет создать внешнюю библиотеку для вызова функции GetVolumeInformation.Следующие примеры кода должны работать для всех комбинаций Delphi и InnoSetup (с точки зрения поддержки Unicode).

Вот код библиотеки Delphi:

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.

А вот код InnoSetup:

[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;
...