【问题标题】:Inno Setup: Dynamically add a component for all files in a folder and its subfoldersInno Setup:为文件夹及其子文件夹中的所有文件动态添加组件
【发布时间】:2017-12-16 23:15:14
【问题描述】:

Inno Setup:动态添加文件夹中的所有文件并添加组件标签,因此在运行设置期间用户可以选择自定义设置并选择要复制的文件。

我想创建一个 Inno Setup 文件,该文件将抓取用户可以放入其中的文件夹中的文件,而无需在每次添加新文件时修改 Inno Setup 文件。同时,我需要安装文件的用户能够选择要复制的文件。

如果我这样做:

Source: "D:\SomeDirectory\*"; DestDir: "{app}"; \
   Flags: ignoreversion recursesubdirs createallsubdirs; Components: dlls

自定义设置仅显示复制或不复制整个文件夹的选项。

【问题讨论】:

  • "文件夹中的文件" - 什么文件夹?编译时还是运行时?
  • 你需要递归吗?

标签: file components inno-setup


【解决方案1】:

假设文件在编译时可用,您可以使用Inno Setup Preprocessor 递归宏来生成[Files][Components] 部分。

此代码部分基于Generating Inno Setup file flags programmatically

#pragma parseroption -p-

#define FileEntry(Source, Dest) \
    Local[0] = Copy(Dest, 2, Len(Dest) - 1), \
    Local[1] = StringChange(Local[0], ".", ""), \
    "[Files]\n" + \
    "Source: " + Source + "; DestDir: {app}" + ExtractFileDir(Dest) + \
        "; Components: " + Local[1] + "\n" + \
    "[Components]\n" + \
    "Name: " + Local[1] + "; Description: " + ExtractFileName(Dest) + "\n"

#define DirEntry(Source, Dest) \
    Local[0] = Copy(Dest, 2, Len(Dest) - 1), \
    Local[1] = StringChange(Local[0], ".", ""), \
    "[Components]\n" + \
    "Name: " + Local[1] + "; Description: " + ExtractFileName(Dest) + "\n"

#define ProcessFile(Source, Dest, FindResult, FindHandle) \
    FindResult \
        ? \
            Local[0] = FindGetFileName(FindHandle), \
            Local[1] = Source + "\\" + Local[0], \
            Local[2] = Dest + "\\" + Local[0], \
            (Local[0] != "." && Local[0] != ".." \
                ? (DirExists(Local[1]) \
                     ? DirEntry(Local[1], Local[2]) + ProcessFolder(Local[1], Local[2]) \
                     : FileEntry(Local[1], Local[2])) \
                : "") + \
            ProcessFile(Source, Dest, FindNext(FindHandle), FindHandle) \
        : \
            ""

#define ProcessFolder(Source, Dest) \
    Local[0] = FindFirst(Source + "\\*", faAnyFile), \
    ProcessFile(Source, Dest, Local[0], Local[0])

#pragma parseroption -p+

#emit ProcessFolder("D:\SomeDirectory", "")

如果D:\SomeDirectory 包含这些文件:

file1.txt
file2.txt
sub1\file11.txt
sub1\file12.txt
sub2\file21.txt
sub2\file22.txt

上面的代码会生成:

[Files]
Source: D:\SomeDirectory\file1.txt; DestDir: {app}; Components: file1txt
[Components]
Name: file1txt; Description: file1.txt
[Files]
Source: D:\SomeDirectory\file2.txt; DestDir: {app}; Components: file2txt
[Components]
Name: file2txt; Description: file2.txt
[Components]
Name: sub1; Description: sub1
[Files]
Source: D:\SomeDirectory\sub1\file11.txt; DestDir: {app}\sub1; Components: sub1\file11txt
[Components]
Name: sub1\file11txt; Description: file11.txt
[Files]
Source: D:\SomeDirectory\sub1\file12.txt; DestDir: {app}\sub1; Components: sub1\file12txt
[Components]
Name: sub1\file12txt; Description: file12.txt
[Components]
Name: sub2; Description: sub2
[Files]
Source: D:\SomeDirectory\sub2\file21.txt; DestDir: {app}\sub2; Components: sub2\file21txt
[Components]
Name: sub2\file21txt; Description: file21.txt
[Files]
Source: D:\SomeDirectory\sub2\file22.txt; DestDir: {app}\sub2; Components: sub2\file22txt
[Components]
Name: sub2\file22txt; Description: file22.txt

在安装程序中,您将获得:


请注意,您可以通过这种方式处理的文件数量受预处理器堆栈的限制。

如果你被它击中,另一种(虽然丑陋和复杂)的方法是使用用户定义的过程。有关使用此处显示的方法和使用用户定义的过程来实现递归文件处理的示例,请参阅Inno Setup - Recurse sub directories without creating those same sub directories

【讨论】:

  • 这正是我想要的,而且效果很好!谢谢。
  • 跟进这个,试图弄清楚如何添加文件扩展名必须是dll的要求。
  • 我想通了!第 39 行 (Local[0] != "." && Local[0] != ".." && 小写(ExtractFileExt(Local[0])) == "dll" \
猜你喜欢
  • 2014-01-14
  • 1970-01-01
  • 2015-02-16
  • 2019-06-19
  • 1970-01-01
  • 2011-09-09
  • 1970-01-01
  • 2015-03-29
  • 1970-01-01
相关资源
最近更新 更多