使用 Inno Setup 将文件复制到从注册表读取的多个目的地

问题描述 投票:0回答:1

我在

[Files]
部分中使用这些行将文件复制到软件已安装版本的目录中,而每个版本都有多个地址:(例如
R21.0
是软件的一个版本)

[Files]
Source: "Fonts\*"; DestDir: {code:GetDir|R21.0};
Source: "Fonts\*"; DestDir: {code:GetDir|R22.0};
Source: "Fonts\*"; DestDir: {code:GetDir|R23.1};
Source: "Fonts\*"; DestDir: {code:GetDir|R24.0};
Source: "Fonts\*"; DestDir: {code:GetDir|R24.1};

这是

GetDir
功能:

function GetDir(AcadVerNames: string): String;
var
  AcadRegKey, sAcadLoc: String;
begin
  RootKeyU := HKEY_CURRENT_USER_64;  
   
  if RegGetSubkeyNames(RootKey, 'SOFTWARE\Autodesk\AutoCAD' + '\' + AcadVerNames, AcadVerKeysTemp) then
  begin
    for I := 0 to GetArrayLength(AcadVerKeysTemp)-1 do
    begin
      RegQueryStringValue(RootKeyU, 'SOFTWARE\Autodesk\AutoCAD' + '\' + AcadVerNames + '\'  + AcadVerKeysTemp[I] , 'RootFolder', sAcadLoc);
    end;
  end;
   
  Result := sAcadLoc + '\Fonts';
end;

问题是

AcadVerNames
有两个结果,换句话说每个版本有两个位置。此函数仅返回版本中子文件夹的一个目的地

在这个系统中,只安装了两个版本,复制文件的目的地存储在每个版本的子文件夹中,子文件夹不固定,每个版本在注册表中可能有一个、两个或三个子文件夹。

installation inno-setup pascalscript
1个回答
1
投票

您可以使用这样的解决方案:
如何将同一文件安装到多个位置(Inno Setup)

您只需要一个额外的参数来查询每个版本的第n个目录。

类似这样的:

[Files]
Source: "Fonts\*"; DestDir: {code:GetDir|R21.0,0}; Check: HasDir('R21.0', 0)
Source: "Fonts\*"; DestDir: {code:GetDir|R21.0,1}; Check: HasDir('R21.0', 1)
Source: "Fonts\*"; DestDir: {code:GetDir|R21.0,2}; Check: HasDir('R21.0', 2)
const
  AcadRegRoot = HKCU64;
  AcadRegKeyRoot = 'SOFTWARE\Autodesk\AutoCAD';

function GetDir(Param: string): string;
var
  AcadRegKey: string;
  Names: TArrayOfString;
  I, P: Integer;
begin
  P := Pos(',', Param);
  AcadVerNames := Copy(Param, 1, P - 1);
  AcadRegKey := AcadRegKeyRoot + '\' + AcadVerNames;
  if RegGetSubkeyNames(AcadRegRoot, AcadRegKey, Names) then
  begin
    I := StrToInt(Copy(Param, P + 1, Length(Param) - P));
    AcadRegKey := AcadRegKey + '\' + Names[I];

    if RegQueryStringValue(AcadRegRoot, AcadRegKey, 'RootFolder', Result) then
      Result := Result + '\Fonts';
  end;
end;

function HasDir(AcadVerNames: string; I: Integer): Boolean;
var
  AcadRegKey: string;
  Names: TArrayOfString;
begin
  AcadRegKey := AcadRegKeyRoot + '\' + AcadVerNames;
  Result :=
    RegGetSubkeyNames(AcadRegRoot, AcadRegKey, Names) and
    (GetArrayLength(Names) > I);
end;

与此处所示类似,您可以使用 预处理器 来避免重复:

[Files]
#define FontsForReleaseN(Ver, N) \
  "Source: ""Fonts\*""; DestDir: {code:GetDir|" + Ver + "," + Str(N) +"}; " + \
  "Check: HasDir('" + Ver + "'," + Str(N) + ")" + NewLine
#define FontsForRelease(Ver) \
  FontsForReleaseN(Ver, 0) + FontsForReleaseN(Ver, 1) + FontsForReleaseN(Ver, 2)

#emit FontsForRelease('R21.0')
#emit FontsForRelease('R22.0')
#emit FontsForRelease('R23.1')
...

未经测试,但它应该可以给你这个想法。


其他选择是放弃

Files
部分并使用 Pascal 代码安装所有内容。这更简单。但如果你需要在 GUI 中显示进度,那就更复杂了。

© www.soinside.com 2019 - 2024. All rights reserved.