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

时间:2017-07-12 13:31:57

标签: file components inno-setup

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

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

如果我这样做:

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

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

1 个答案:

答案 0 :(得分: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

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

enter image description here

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

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