How to generate a new GUID in Inno Setup?
Asked Answered
A

5

10

Is there a way to generate a new GUID from inside the Inno Setup script ?

Alphonsoalphonsus answered 28/8, 2009 at 13:45 Comment(0)
H
14

Found this on innosetup newsgroup archive:

http://news.jrsoftware.org/news/innosetup/msg76234.html

I haven't tested it.

[Code]

type
  TGUID = record
    D1: LongWord;
    D2: Word;
    D3: Word;
    D4: array[0..7] of Byte;
  end;

function CoCreateGuid(var Guid:TGuid):integer;
 external '[email protected] stdcall';

function inttohex(l:longword; digits:integer):string;
var hexchars:string;
begin
 hexchars:='0123456789ABCDEF';
 setlength(result,digits);
 while (digits>0) do begin
  result[digits]:=hexchars[l mod 16+1];
  l:=l div 16;
  digits:=digits-1;
 end;
end;

function GetGuid(dummy:string):string;
var Guid:TGuid;
begin
  if CoCreateGuid(Guid)=0 then begin
  result:='{'+IntToHex(Guid.D1,8)+'-'+
           IntToHex(Guid.D2,4)+'-'+
           IntToHex(Guid.D3,4)+'-'+
           IntToHex(Guid.D4[0],2)+IntToHex(Guid.D4[1],2)+'-'+
           IntToHex(Guid.D4[2],2)+IntToHex(Guid.D4[3],2)+
           IntToHex(Guid.D4[4],2)+IntToHex(Guid.D4[5],2)+
           IntToHex(Guid.D4[6],2)+IntToHex(Guid.D4[7],2)+
           '}';
  end else
    result:='{00000000-0000-0000-0000-000000000000}';
end;

function InitializeSetup(): Boolean;
begin
  MsgBox(GetGuid(''), mbInformation, MB_OK);
  Result := False;
end;
Holp answered 28/8, 2009 at 13:56 Comment(3)
Also, there's another win32 API call that converts the raw GUID from CoCreateGuid() into a string representation in the format {00000000-0000-0000-0000-000000000000}, which would greatly simplify the above function, but I don't remember what it's named.Embranchment
StringFromCLSID is the second win32 API call to use for this, also from ole32.dll.Embranchment
When I updated to 5.5.2 (unicode) - my build scripts failed because of a duplicate type error: 'TGUID'.Mudslinging
H
3

Here's a somewhat cleaner implementation of FormatGuid, without the unnecessary hex-formatting function (what do we have Format for?!):

function FormatGuid(Guid:TGuid):string;
begin
  result:=Format('%.8x-%.4x-%.4x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x', [Guid.D1, Guid.D2, Guid.D3, Guid.D4[0], Guid.D4[1], Guid.D4[2], Guid.D4[3], Guid.D4[4], Guid.D4[5], Guid.D4[6], Guid.D4[7]]);
end;

You still need to define TGuid and import CoCreateGuid as in the other answers:

type
  TGuid = record
    D1: LongWord;
    D2: Word;
    D3: Word;
    D4: array[0..7] of Byte;
  end;

function CoCreateGuid(var Guid:TGuid):integer;
 external '[email protected] stdcall';
Herpetology answered 5/5, 2011 at 1:0 Comment(2)
Unfortunately, the result of the FormatGuid function in this answer did not produce a string representation of a GUID in a valid format. Instead, a string was produced as below XXXXXXXX-XXXX-XXXX-XX-XX-XX-XX-XX-XX-XX-XX Validation was carried out via guid.us/Test/GUIDSheeting
An alternative string format is shown at: docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/… This format appeared to produce valid GUIDs according to guid.us/Test/GUIDSheeting
P
3

I was using this solution for a while (running 5.5.0 (a) and 5.5.1(a)).

However, when I updated to 5.5.2 (u) - my build scripts failed because of a duplicate type error: 'TGUID'.

In order to fix it, I had to remove:

type
  TGUID = record
    D1: LongWord;
    D2: Word;
    D3: Word;
    D4: array[0..7] of Byte;
  end;

This is only happening on the Unicode version - meaning 5.5.2 (u) has a built in GUID type.

Pyrrhotite answered 9/11, 2012 at 17:17 Comment(0)
P
2

Based on the answer and comments from MusiGenesis and giorgian, here is a version that uses the StringFromGUID2 Win32 call for formatting the GUID.

Tested in Inno Setup 6.2

function CoCreateGuid(var Guid : TGuid): integer;
external '[email protected] stdcall';

function StringFromGUID2(var rguid : TGuid; lpsz : string; cchMax : integer): integer;
external '[email protected] stdcall';

function GenerateGUID(): string;
var
    Guid: TGuid;
    GuidString: string;
    GuidLength: integer;
begin
  if CoCreateGuid(Guid) = 0 then
  begin
    GuidString := '';
    SetLength(GuidString, 100);
    GuidLength := StringFromGUID2(Guid, GuidString, 100);
    if GuidLength > 0 then
    begin
        SetLength(GuidString, GuidLength - 1);
        Result := GuidString;
    end else begin
        RaiseException('GUID conversion to string failed');
    end;
  end else begin
    RaiseException('GUID creation failed');
  end;
end;

resulting uuid

Parcenary answered 4/11, 2022 at 13:47 Comment(1)
Best solution. Note: if you want to refer to this in the installer, add a dummy param to the function so you can refer to {code:GenerateGUID}.Petite
E
1

You can do this by calling the Windows API function CoCreateGuid (in "OLE32.dll"), which you declare inside a [Code] section in your script. Sorry, I haven't used Inno Setup in awhile so I don't know exactly how to do this. To help, here's a sample API declaration for the GetWindow() function:

Function GetWindow (HWND: Longint; uCmd: cardinal): Longint;
    external '[email protected] stdcall';

And here's a link to a VB sample for using CoCreateGuid:

http://support.microsoft.com/kb/176790

Somewhere in all of this is your answer.

Embranchment answered 28/8, 2009 at 13:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.