问题描述
我想为 Inno Setup 创建一个脚本,其中安装路径将从定义目录中的文件中获取 - 没有注册表。我想它需要为它编写特定的代码,在那里定义一些变量,这些变量将包含读取文件后的值。任何用户的文件路径和名称始终相同,因此唯一更改的值是安装路径。
完整结构,其中 InstallLocation
是变量:
{
"FormatVersion": 0,"bIsIncompleteInstall": false,"AppVersionString": "1.0.1",...
"InstallLocation": "h:\\Program Files\\Epic Games\\Limbo",...
}
有什么理想的代码可以做到这一点吗?
谢谢
解决方法
实现 scripted constant 以将值提供给 DefaultDirName
directive。
您可以使用 JsonParser library 来解析 JSON 配置文件。
[Setup]
DefaultDirName={code:GetInstallLocation}
[Code]
#include "JsonParser.pas"
// Here go the other functions the below code needs.
// See the comments at the end of the post.
const
CP_UTF8 = 65001;
var
InstallLocation: string;
<event('InitializeSetup')>
function InitializeSetupParseConfig(): Boolean;
var
Json: string;
ConfigPath: string;
JsonParser: TJsonParser;
JsonRoot: TJsonObject;
S: TJsonString;
begin
Result := True;
ConfigPath := 'C:\path\to\config.json';
Log(Format('Reading "%s"',[ConfigPath]));
if not LoadStringFromFileInCP(ConfigPath,Json,CP_UTF8) then
begin
MsgBox(Format('Error reading "%s"',[ConfigPath]),mbError,MB_OK);
Result := False;
end
else
if not ParseJsonAndLogErrors(JsonParser,Json) then
begin
MsgBox(Format('Error parsing "%s"',MB_OK);
Result := False;
end
else
begin
JsonRoot := GetJsonRoot(JsonParser.Output);
if not FindJsonString(JsonParser.Output,JsonRoot,'InstallLocation',S) then
begin
MsgBox(Format('Cannot find InstallLocation in "%s"',MB_OK);
Result := False;
end
else
begin
InstallLocation := S;
Log(Format('Found InstallLocation = "%s"',[InstallLocation]));
end;
ClearJsonParser(JsonParser);
end;
end;
function GetInstallLocation(Param: string): string;
begin
Result := InstallLocation;
end;
代码使用的函数来自:
-
How to parse a JSON string in Inno Setup?(
ParseJsonAndLogErrors
、ClearJsonParser
、GetJsonRoot
、FindJsonValue
和FindJsonString
); -
Inno Setup - Convert array of string to Unicode and back to ANSI(
MultiByteToWideChar
和LoadStringFromFileInCP
)。