我正在使用Inno Setup #define指令来定义安装程序中有关软件包的所有信息,然后使用其他指令来提取该字符串的部分内容。例如,使用以下内容,PartNumber(Package1)
将返回05414。
#define Package1 "05414 - My Package"
#define PartNumber(str Package) Copy(Package, 1, 5)
我在脚本和代码中使用这种方法,它工作正常。但是,我有一种情况,以编程方式生成字符串将很方便,我无法让它工作。例如,我想做类似以下的事情。
procedure Foo(Package: String);
var
PartNumber: String;
begin
PartNumber:= ExpandConstant(Format('{#PartNumber(%s)}', [Package]));
end;
procedure Bar();
begin
Foo(ExpandConstant('{#Package1)}'));
end;
Package
的{{1}}参数是正确的,但我收到编译错误
[ISPP]格式'%'没有参数。
它似乎不喜欢Foo
行中字符串中的#
。即使在普通字符串中包含PartNumber
也会产生“未终止的预处理程序指令”错误,因此我认为它将#
解释为精度说明符或其他内容。
有没有办法让它将#
视为文本的一部分,以便我可以通过编程方式扩展此常量?如果没有,如果有其他方式我可以做到这一点?
答案 0 :(得分:1)
这不起作用。
PartNumber
是preprocessor function/macro。它在编译时进行评估。它在运行时不存在。
当然,您可以实现等效的Pascal脚本函数:
function PartNumberPascal(Package: string): string;
begin
Result := Copy(Package, 1, 5);
end;
procedure Foo(Package: String);
var
PartNumber: String;
begin
PartNumber := PartNumberPascal(Package);
end;
这可能让您感到困惑,是这个电话:
Foo(ExpandConstant('{#Package1}'));
这可能会让您觉得ExpandConstant
function扩展了Package1
预处理器定义。
它没有!
{#...}
语法(与{...}
相反)不是constant。它是inline preprocessor directive call,其中,当没有明确指定指令时,隐含emit
。因此{#Package1}
与{#emit Package1}
相同。并且作为每个预处理器构造,它在编译时进行评估。
如果您add SaveToFile
preprocessor function call到脚本的末尾:
procedure Bar();
begin
Foo(ExpandConstant('{#Package1}'));
end;
#expr SaveToFile(AddBackslash(SourcePath) + "Preprocessed.iss")
编译完成后,检查Preprocessed.iss
是什么样的。你会看到:
procedure Bar();
begin
Foo(ExpandConstant('05414 - My Package'));
end;
Package1
扩展到其值。但是ExpandConstant
仍然存在,因此它完全没用! ('05414 - My Package'
)
这会产生同样的效果:
procedure Bar();
begin
Foo('{#Package1}');
end;