如何在Inno Setup中生成新的GUID?

10

有没有一种方法可以在Inno Setup脚本中生成一个新的GUID?

5个回答

14

在innosetup新闻组档案中找到了这个:

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

我没有测试过。

[Code]

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

function CoCreateGuid(var Guid:TGuid):integer;
 external 'CoCreateGuid@ole32.dll 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;

1
此外,还有另一个win32 API调用可以将来自CoCreateGuid()的原始GUID转换为格式为{00000000-0000-0000-0000-000000000000}的字符串表示形式,这将极大地简化上述函数,但我不记得它的名称是什么。 - MusiGenesis
2
StringFromCLSID是第二个Win32 API调用,也来自ole32.dll。 - MusiGenesis
2
当我更新到5.5.2(unicode)时,我的构建脚本因重复类型错误'TGUID'而失败。 - bgcode

3

我曾经使用这个解决方案有一段时间 (运行版本为5.5.0 (a) 和 5.5.1(a))。

然而,当我升级到5.5.2(u)时,我的构建脚本由于重复类型错误'TGUID'而失败。

为了解决这个问题,我不得不移除:

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

这只发生在Unicode版本上,也就是说5.5.2 (u)内置了GUID类型。

3

这是一个相对较为简洁的 FormatGuid 实现,没有必要的十六进制格式化函数(我们有 Format 函数来干嘛的?!):

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;

您仍需要像其他答案中那样定义TGuid并导入CoCreateGuid:

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

function CoCreateGuid(var Guid:TGuid):integer;
 external 'CoCreateGuid@ole32.dll stdcall';

1
很遗憾,此答案中的FormatGuid函数结果未能生成有效格式的GUID字符串表示形式。相反,生成了以下字符串 XXXXXXXX-XXXX-XXXX-XX-XX-XX-XX-XX-XX-XX-XX验证是通过http://guid.us/Test/GUID进行的。 - pb.
备选的字符串格式在以下网址中显示: http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/System_TGUID.html根据 http://guid.us/Test/GUID,这种格式似乎可以生成有效的 GUID。 - pb.

1

基于 MusiGenesis 和 giorgian 的回答和评论,这里提供了一种使用 StringFromGUID2 Win32 调用格式化 GUID 的版本。

在 Inno Setup 6.2 中测试通过。

function CoCreateGuid(var Guid : TGuid): integer;
external 'CoCreateGuid@ole32.dll stdcall';

function StringFromGUID2(var rguid : TGuid; lpsz : string; cchMax : integer): integer;
external 'StringFromGUID2@ole32.dll 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


1

您可以通过在脚本中的 [Code] 部分声明 Windows API 函数 CoCreateGuid(在 "OLE32.dll" 中)并调用它来实现此操作。抱歉,我已经有一段时间没有使用 Inno Setup 了,所以我不知道具体该如何操作。为了帮助您,这里提供了一个 GetWindow() 函数的示例 API 声明:

Function GetWindow (HWND: Longint; uCmd: cardinal): Longint;
    external 'GetWindow@user32.dll stdcall';

这里有一个使用CoCreateGuid的VB示例链接:

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

在所有这些中,你的答案就在其中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接