在 Inno Setup Pascal 脚本中评估运行时的预处理器宏

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

我使用 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
。 即使在普通字符串中包含
#
也会产生“未终止的预处理器指令”错误,所以我认为它将
#
解释为精度说明符或其他东西。

有没有办法让它将

#
视为文本的一部分,以便我可以以编程方式扩展这个常量? 如果没有,是否有其他方法可以实现这一目标?

inno-setup
1个回答
4
投票

这行不通。

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;

类似问题请参见:
在 Inno Setup Pascal 脚本中运行时评估来自预处理器的数据集合

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