当前位置: 首页 > 知识库问答 >
问题:

Inno Setup:为文件夹及其子文件夹中的所有文件动态添加组件

皇甫文乐
2023-03-14

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

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

如果我做了这样的事情:

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

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

共有1个答案

方弘
2023-03-14

假设文件在编译时可用,您可以使用Inno Setup预处理程序递归宏来生成< code>[Files]和< code>[Components]部分。

这段代码部分基于以编程方式生成Inno Setup文件标志。

#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", "")

如果< code>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子目录,而不创建相同的子目录。

 类似资料:
  • 问题内容: 我如何返回一个包含该文件夹中的所有文件以及子文件夹的文件数组,我的方法仅适用于该文件夹,并且不包括子文件夹。 问题答案: 使用您当前的代码,进行以下调整:

  • 我正在寻找一种方法来获取zip文件中的文件列表。我创建了一个方法来获取目录中的文件列表,但我也在寻找一种方法来获取zip文件中的文件,而不是只显示zip文件。 以下是我的方法:

  • 我在文件中有这一行: 哪个包文件夹< code>Tcl。但是它只获取文件夹中的文件,而不获取< code>Tcl中的子文件夹。有没有办法把整个文件夹< code>Tcl连同所有子文件夹和文件?(不逐行列出所有子文件夹)。 Inno设置5.4.2。

  • 问题内容: 这个问题已经在这里有了答案 : 使用Java将文件从一个目录复制到另一个目录 (33个答案) 4年前关闭。 如何将一个文件夹及其所有子文件夹和文件复制到另一个文件夹中? 问题答案: Apache Commons IO可以为您解决问题。看看FileUtils。

  • 我尝试搜索一个命令,该命令可以使用命令提示符命令列出目录中的所有文件以及子文件夹。我已经阅读了“dir”命令的帮助,但找不到我要查找的内容。请帮助我什么命令可以得到这个。

  • 问题内容: 我对Swift编程非常陌生,并且正在尝试遍历文件夹中的文件。我在这里查看了答案,并尝试将其转换为Swift语法,但未成功。 我得到的错误是: 我的目的是查看主文件夹中包含的所有子文件夹和文件,并找到所有具有特定扩展名的文件,然后对它们进行处理。 问题答案: 使用以下方法: