在Inno Setup Pascal脚本中在运行时评估预处理器宏 [英] Evaluate preprocessor macro on run time in Inno Setup Pascal Script
问题描述
我正在使用Inno Setup #define指令来定义安装程序中有关软件包的所有信息,然后使用其他指令来提取该字符串的某些部分.因此,例如,使用以下命令,PartNumber(Package1)
将返回05414.
I'm using an Inno Setup #define directive to define all of the information about a software package in my installer and then other directives to extract portions of that string. So for example, using the following, PartNumber(Package1)
will return 05414.
#define Package1 "05414 - My Package"
#define PartNumber(str Package) Copy(Package, 1, 5)
我在脚本和代码中使用了这种方法,并且效果很好.但是,我遇到了这样一种情况,即以编程方式生成字符串会很方便,而且我无法使其正常工作.例如,我想执行以下操作.
I'm using this approach in scripts and code and it works fine. However, I've got a situation where it would be convenient to programmatically generate the string and I'm having trouble getting it to work. For example, I'd like to do something like the following.
procedure Foo(Package: String);
var
PartNumber: String;
begin
PartNumber:= ExpandConstant(Format('{#PartNumber(%s)}', [Package]));
end;
procedure Bar();
begin
Foo(ExpandConstant('{#Package1)}'));
end;
Foo
的Package
参数是正确的,但是出现编译器错误
The Package
argument to Foo
is correct, but I get a compiler error saying
[ISPP]无格式'%'的参数."
[ISPP] No argument for format '%'".
似乎不喜欢PartNumber
行中字符串中的#
.即使在普通字符串中包含#
也会产生未终止的预处理程序指令"错误,因此我认为它会将#
解释为精度说明符或其他内容.
It seems that it doesn't like the #
in the string on the PartNumber
line. Even including a #
in a normal string gives an "unterminated preprocessor directive" error, so I think it's interpreting the #
as a precision specifier or something.
是否有一种方法可以将#
视为文本的一部分,以便我可以以编程方式扩展此常量?如果没有,还有其他方法可以实现吗?
Is there a way to make it treat #
as part of the text so that I can programmatically expand this constant? If not, if there some other way I can achieve this?
推荐答案
这不起作用.
PartNumber
是预处理器功能/宏.它是在编译时评估的.它在运行时不存在.
The PartNumber
is a preprocessor function/macro. It's evaluated on compile time. It does not exist on run time.
您当然可以实现等效的Pascal脚本功能:
You can, of course, implement an equivalent Pascal Script function:
function PartNumberPascal(Package: string): string;
begin
Result := Copy(Package, 1, 5);
end;
procedure Foo(Package: String);
var
PartNumber: String;
begin
PartNumber := PartNumberPascal(Package);
end;
这个电话可能会让您感到困惑:
What probably confuses you, is this call:
Foo(ExpandConstant('{#Package1}'));
可能会给您留下 ExpandConstant
函数展开的印象Package1
预处理器定义.
It may give you an impression that the ExpandConstant
function expands the Package1
preprocessor define.
不是!
{#...}
语法(与{...}
相反)不是常量.这是内联预处理程序指令调用,其中,当未明确指定指令时,暗示 emit
.因此,{#Package1}
与{#emit Package1}
相同.作为每个预处理器构造,它都在编译时进行评估.
The {#...}
syntax (contrary to the {...}
) is not a constant. It's an inline preprocessor directive call, where, when no directive is explicitly specified, the emit
is implied. So the {#Package1}
is the same as {#emit Package1}
. And as every preprocessor construct, it's evaluated on compile time.
如果您在脚本末尾添加SaveToFile
预处理程序函数调用:
If you add SaveToFile
preprocessor function call to the end of the script:
procedure Bar();
begin
Foo(ExpandConstant('{#Package1}'));
end;
#expr SaveToFile(AddBackslash(SourcePath) + "Preprocessed.iss")
然后在编译后,检查Preprocessed.iss
是什么样的.您将看到:
And after compilation, check, what the Preprocessed.iss
is like. You will see:
procedure Bar();
begin
Foo(ExpandConstant('05414 - My Package'));
end;
Package1
会扩展为其值.但是ExpandConstant
仍然存在,因此完全没有用! ('05414 - My Package'
中没有常量)
The Package1
is expanded to its value. But the ExpandConstant
is still there, and hence it's totally useless! (there are no constants in the '05414 - My Package'
)
这将具有相同的效果:
procedure Bar();
begin
Foo('{#Package1}');
end;
有关类似问题,请参见:
在运行时使用Inno Setup Pascal脚本评估预处理器中的数据集合
For a similar question, see:
Evaluate a collection of data from preprocessor on run time in Inno Setup Pascal Script
这篇关于在Inno Setup Pascal脚本中在运行时评估预处理器宏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!