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

问题描述 投票:0回答:1

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

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

如果我做这样的事情:

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

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

file components inno-setup
1个回答
3
投票

假设文件在编译时可用,您可以使用 Inno Setup Preprocessor 递归宏来生成

[Files]
[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", "")

如果

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 中创建相同的子目录

© www.soinside.com 2019 - 2024. All rights reserved.