我使用 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
Foo
的参数是正确的,但我收到编译器错误:
[ISPP] 格式“%”没有参数。
看起来它不喜欢
#
行字符串中的PartNumber
。 即使在普通字符串中包含 #
也会产生“未终止的预处理器指令”错误,所以我认为它将 #
解释为精度说明符或其他东西。
有没有办法让它将
#
视为文本的一部分,以便我可以以编程方式扩展这个常量? 如果没有,是否有其他方法可以实现这一目标?
这行不通。
PartNumber
是一个预处理器函数/宏。它是在编译时评估的。它在运行时不存在。
当然,您可以实现等效的 Pascal Script 函数:
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
函数扩展了Package1
预处理器定义。
没有!
{#...}
语法(与{...}
相反)不是常量。这是一个内联预处理器指令调用,其中,当没有显式指定指令时,会隐含emit
。所以 {#Package1}
与 {#emit Package1}
相同。作为每个预处理器构造,它都会在编译时进行评估。
如果您添加
SaveToFile
预处理器函数调用到脚本末尾:
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;