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

Inno Setup-重复子目录,而不创建相同的子目录

杭柏
2023-03-14

我经常使用recursesubdirs标志遍历多个子目录,并提取特定文件或文件类型,而不必单独明确引用每个文件。例子:

Source: C:\kh25\dependencies\*.dll; DestDir: {app}; Flags: recursesubdirs

这会在我的目标{app}路径中创建与最初检索DLL的源完全相同的目录结构。例如,如果我从上面的C:\kh25\依赖项\test检索了一个DLL,那么它会将该DLL放在{app}\test路径中。

这种行为可以通过以下方式进行修改:

Source: C:\kh25\dependencies\test\*.dll; DestDir: {app}; Flags: recursesubdirs

但显然,这意味着我必须单独引用依赖关系中的每个子目录。

因此,64000美元的问题是,如何防止在目标中重新创建相同的目录,而不必显式引用源目录?

共有1个答案

印子平
2023-03-14

使用Inno Setup预处理器生成< code>[Files]部分的条目。

一种可能的解决方案(而且相对简单)是使用递归宏,如:

#pragma parseroption -p-

#define FileEntry(Source) \
    "Source: " + Source + "; DestDir: {app}\n"

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

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

#pragma parseroption -p+

#emit ProcessFolder("C:\kh25\dependencies")

尽管此解决方案有其局限性,并且可能会使预处理器崩溃,具有大量文件或深度目录结构(适用于数千个文件)。

受@Zlatko Karaka的答案启发,使用Inno Setup预处理器来获取源文件路径及其子目录的文件和大小。

更可靠(丑陋而复杂)的解决方案是使用用户定义的过程。这很复杂,因为预处理器缺乏对用户定义过程参数的支持。

[Files]

#define FindHandle
#define FindResult 
#dim InnerMask[65536]
#define InnerMask[0] ""

#sub ProcessFoundFile
    #define InnerFileName FindGetFileName(FindHandle)
    #define fileName InnerMask[InnerMaskWorkPosition] + InnerFileName
    #if InnerFileName!="." && InnerFileName!=".."
        #if DirExists(FileName)
            #define Public InnerMask[InnerMaskPosition] FileName+"\"
            #define Public InnerMaskPosition InnerMaskPosition + 1
        #else
            Source: {#FileName}; DestDir: {app}
        #endif
    #endif 
#endsub

#sub ProcessInnerMaskPosition 
    #for { \
        FindHandle = FindResult = \
            FindFirst(InnerMask[InnerMaskWorkPosition]+"*", faAnyFile); \
        FindResult; FindResult = FindNext(FindHandle)} ProcessFoundFile
    #if FindHandle
        #expr FindClose(FindHandle)
    #endif
#endsub

#sub CollectFiles
    #define Public InnerMaskPosition 1
    #define Public InnerMaskWorkPosition 0
    #for { \
        InnerMaskWorkPosition = 0; InnerMaskWorkPosition < InnerMaskPosition; \
            InnerMaskWorkPosition++} \
            ProcessInnerMaskPosition
    #undef Public InnerMaskPosition
    #undef Public InnerMaskWorkPosition
#endsub

#expr InnerMask[0]="C:\kh25\dependencies\"
#expr CollectFiles

递归扫描函数取自@René Martin的答案,使用Inno Setup预处理器来获取源路径及其子目录的文件和大小。

在 Inno 安装程序脚本的最后添加 SaveToFile 调用,请参阅预处理器生成的内容:

#expr SaveToFile(AddBackslash(SourcePath) + "Preprocessed.iss")

请参阅Inno Setup:如何查看Inno Setup预处理器的输出(转换)?

我对这个问题的回答解释了上面采用的两种方法之间的区别:
Inno Setup预处理器可以用于构建一组重复的自定义消息吗?

 类似资料:
  • 您好,我想用java创建目录和子目录。我的目录结构是从当前应用程序目录开始的,意思是在当前项目目录中,如下所示。。。 我知道如何创建目录,但我需要创建子目录,我用下面的代码尝试了,下一步应该做什么?

  • 当文档很多时,那么,你需要用到 子目录 了。 根目录下 index.rst 加入 modelList/index ;在目录中,index.rst 文件,可以写为 源码 模块列表 ---------- .. toctree:: :glob: :titlesonly: * 引入 rst 文件 警告 这里是 引入的 rst 文件。 源码 .. hea

  • 有人知道如何将playbooks放入文件夹,但共享相同的角色、group_vars和其他通常位于根目录的东西吗? 这将获取main.yml中定义的var。但是,我不清楚这是否会添加在group_vars/中定义的组变量,而不是显式指定的.../group_vars/。 谢了!

  • sbt子项目是否可以有自己的目录?或者只有根项目可以用。Scala帮助器文件为构建项目的目录?。下面是我目前的建筑结构。无法访问中定义的对象。 更新:sub-project-1/build.sbt中的以下sbt定义 由于以下错误而失败 Common在/my-project/projects/Common.scala中定义,没有问题。但是Localhost是在/my-project/sub-proj

  • 我使用一个Android库,它要求我创建两个类,每个类继承自不同的类 (具有公共基类) 现在我有这个代码: 我必须复制这个类来创建一个扩展,即使我的两个类共享完全相同的代码。 我简化了示例的代码,但重复可能很重要 我决定将代码放在这两个类之外的静态方法中,并在类重写的方法中调用它们,但我认为必须有一种更干净的方法来做到这一点。 你能帮我解决这个问题吗? 和都继承自。

  • 问题内容: 我正在创建一个简单的程序,尝试从磁盘中读取“ conf / conf.xml”,但是如果此文件或目录不存在,则会创建它们。 我可以使用以下代码执行此操作: 我的问题是,这是否真的是最优雅的方式?需要创建两个简单的路径以在新的子目录中创建新文件似乎多余。 问题答案: 您可以将声明为,而不是。然后,您可以使用,请参见下面的示例: 或者,按原样使用代码,您可以使用: