在Inno Setup Pascal脚本中在运行时评估预处理器宏 [英] Evaluate preprocessor macro on run time in Inno Setup Pascal Script

查看:95
本文介绍了在Inno Setup Pascal脚本中在运行时评估预处理器宏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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;

FooPackage参数是正确的,但是出现编译器错误

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆