Inno setup Inno Setup-递归子目录而不创建相同的子目录
我经常使用Inno setup Inno Setup-递归子目录而不创建相同的子目录,inno-setup,Inno Setup,我经常使用recursesubdirs标志遍历多个子目录并提取特定文件或文件类型,而不必单独显式引用每个文件。例如: Source: C:\kh25\dependencies\*.dll; DestDir: {app}; Flags: recursesubdirs 这将在我的目标{app}路径中创建与最初从中检索DLL的源路径完全相同的目录结构。例如,如果我从上面的C:\kh25\dependencies\test中检索到一个DLL,那么它会将该DLL放在{app}\test路径中 可以通过以
recursesubdirs
标志遍历多个子目录并提取特定文件或文件类型,而不必单独显式引用每个文件。例如:
Source: C:\kh25\dependencies\*.dll; DestDir: {app}; Flags: recursesubdirs
这将在我的目标{app}
路径中创建与最初从中检索DLL的源路径完全相同的目录结构。例如,如果我从上面的C:\kh25\dependencies\test
中检索到一个DLL,那么它会将该DLL放在{app}\test
路径中
可以通过以下操作修改此行为:
Source: C:\kh25\dependencies\test\*.dll; DestDir: {app}; Flags: recursesubdirs
但显然,这意味着我必须单独引用依赖项中的每个子目录
因此$64000的问题是,如何防止在目标中重新创建相同的目录,而不必显式引用源目录?用于生成[文件]
部分的条目
一种可能的解决方案(且相对较好且简单)是使用递归宏,如:
#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")
尽管此解决方案有其局限性,并且可能会使具有大量文件或深层目录结构的预处理器崩溃(适用于数千个文件)
灵感来源于《到》
更可靠(丑陋而复杂)的解决方案是使用用户定义的过程。这很复杂,因为预处理器缺乏对用户定义过程参数的支持
[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
看
我对这个问题的回答解释了上述两种方法之间的差异:
谢谢你,马丁。工作比我希望的多,但我想你不可能赢得所有的工作。
#expr SaveToFile(AddBackslash(SourcePath) + "Preprocessed.iss")