【问题标题】:How to declare an Inno Setup preprocessor variable by reading from a file如何通过从文件中读取来声明 Inno Setup 预处理器变量
【发布时间】:2013-01-25 21:15:00
【问题描述】:

好的,我知道您可以在 Inno Setup 中执行此操作:

#define AppVer "0.0.11"

然后像这样使用它

[Setup]
AppVerName={#AppVer}

现在假设我有一个名为 VERSION 的文件,其内容为“0.0.11”。

有没有办法将文件VERSION 的内容以某种方式放入 Inno Setup 预处理器变量中?

【问题讨论】:

  • 你能确认你想在编译时从文件中读取吗?答案中有一些猜测,答案各不相同。
  • 是的,编译时的文件...

标签: inno-setup


【解决方案1】:

使用 ISPP 的 GetFileVersion 函数是首选方法(毕竟您的安装程序版本应该与您的应用程序版本匹配)。因此,如果这是您真正想要做的,您应该接受 jachguate 的回答。

如果您确实想从文本文件而不是可执行文件中读取版本,那么有两种可能性:

第一个:如果你可以修改文件的内部格式,那么你可以通过使它看起来像一个INI文件来大大简化事情:

[Version]
Ver=0.0.11

鉴于此,您可以使用 ISPP 的 ReadIni 函数来检索版本:

#define AppVer ReadIni("ver.ini", "Version", "Ver", "unknown")

如果无法更改文件格式,则第二种选择是使用FileOpenFileReadFileClose ISPP 函数,例如:

#define VerFile FileOpen("ver.txt")
#define AppVer FileRead(VerFile)
#expr FileClose(VerFile)
#undef VerFile

不过,我再说一遍:最好从可执行文件本身获取应用程序版本。这有助于确保一切都匹配,一方面。

【讨论】:

  • 在最终脚本中添加类似[Setup] AppVerName=0.0.11 的文件和简单的#include 这样的文件可能更容易。
  • 是的,同样只有当 OP 可以自定义文件格式时。 (虽然不要使用 AppVerName,但要使用 AppVersion。)
  • 感谢ISPP功能!如果使用 MS Access,.accdb/.accde 文件中没有此类信息,因此我认为函数是唯一的方法。
  • 最后一个例子也可以内联到#define AppVer() Local[0] = FileOpen("ver.txt"), Local[1] = FileRead(Local[0]), FileClose(Local[0]), Local[1]
  • 另请注意,对于ReadIni,相对路径不起作用,请参阅Inno Setup preprocessor can read a file using FileOpen, but not using ReadIni
【解决方案2】:

您可以使用 Inno Setup Pre Proccessor (ISPP) GetFileVersion 函数直接从您的可执行文件中获取版本,如下所示:

[Setup]
#define AppVersion GetFileVersion("MyFile.exe")
#define AppName "My App name"

AppName={#AppName}
AppVerName={#AppName} {#AppVersion}
VersionInfoVersion={#AppVersion}

; etc

如果您正在使用定义,那么您已经在使用 ISPP。

【讨论】:

  • +1。很好的捕获(假设问题是在编译时而不是运行时)。 :-)
  • @Ken 通常,您从编译时已知的文件中获取版本,因此不需要在运行时执行此操作,这可能涉及将文件从安装程序提取到目标计算机只是为了显示版本。
  • 这就是我给你投票的原因。 :-) 问题没有具体说明,我没有发现#define 的使用或解释这种可能性。
【解决方案3】:

如果您想在安装程序的运行时执行此操作(@jachguate 的回答涵盖了另一种可能性,并且可能是您正在寻找的可能性 - 我会留下它以防它在某些时候对其他人有所帮助) ,您可以使用它的 Pascal 脚本来执行此操作。像这样的东西应该可以工作:

[Setup]
AppVer={code:MyVersion}

[Files]
// Other files
Source: "YourVersionFile.txt"; DestDir: "{app}"

[Code]
function MyVersion(Param: String): String;
var
  VersionValue: string;
  VersionFile: string;
begin
  // Default to some predefined value.
  Result := '0.0.0';
  VersionFile := '{app}\YourVersionFile.txt';
  if LoadStringFromFile(VersionFile, VersionValue) then
    Result := VersionValue;
end;

有关更多信息,包括支持的内置函数列表,请参阅帮助文件主题“Pascal 脚本”。

【讨论】:

  • 你需要一个额外的ExpandConstant (取决于何时需要版本,也可能是ExtractTemporaryFile)。但我非常怀疑他们是否想在安装时阅读该版本。
  • 出于某种原因,我有相同的逻辑,但我似乎无法让它工作,因为我在其他地方使用{#SetupSetting("AppVer")},我发现@Miral 似乎是唯一的一个功能正常。
  • 我猜这与编译时和运行时有关,{code:functionName} 被视为运行时值?有人可以对此发表评论吗?
  • @bnns 我已经做到了。代码函数在安装时运行(并且此特定代码不完整,因为它缺少 ExpandConstant 调用)。 {#SetupSetting("AppVer")} 只会复制文字代码常量,在运行时进行扩展。如果该文件在安装时不存在(并且由于缺少ExpandConstant,它永远不会存在),这将始终返回0.0.0
【解决方案4】:

发件人:http://www.jrsoftware.org/ishelp/

支持类似 C 的 #include 指令,该指令将单独文件中的行拉入 #include 指令位置的脚本中。语法是:

#include "filename.txt"

如果文件名不是完全限定的,编译器将在与包含#include 指令的文件相同的目录中查找它。文件名可能以compiler: 为前缀,在这种情况下,它会在编译器目录中查找文件。

【讨论】:

    猜你喜欢
    • 2020-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-02
    • 2018-02-10
    • 1970-01-01
    • 2012-04-05
    • 1970-01-01
    相关资源
    最近更新 更多