Use Inno Setup PreProcessor to get the files and s

2019-02-15 07:13发布

问题:

Can I use Inno Setup PreProcessor to get the files and size of the source path and its subdirs?,

I am doing a Batch Compiler and I need the size to auto-set in [Setup] DiskSpanning True or False

Only can get the size of source,

Somebody can help me?


#define FindHandle
#define FindResult
#define Mask "*.*"
#define size 0
#define allfiles ""


#sub ProcessFoundFile
 #define FileName FindGetFileName(FindHandle)
  #if direxists(Filename) && Filename!="." && Filename!=".."
   #Define Public Mask AddBackSlash(Filename)+"*.*"  
  #else
   #Define Mask "*.*"
  #endif
 #define public allfiles allfiles + " - " +Filename
 #define public size size + FileSize(FileName)  
#endsub


#for {FindHandle = FindResult = FindFirst(Mask, faDirectory); FindResult; FindResult = FindNext(FindHandle)} ProcessFoundFile
#if FindHandle
;  FindClose(FindHandle)
#endif


#IF Size > 2100000000
#DEFINE Span "True"
#ELSE
#DEFINE Span "False"
#ENDIF

[Setup]
DiskSpanning={#Span}
InternalCompressLevel=ultra
DiskClusterSize=2048
CompressionThreads=2
Compression=lzma2/ultra64
SolidCompression=no

回答1:

Ok, so this is a bit old but I want to share my solution though because I came across the same problem and found some kind of a solution:

#define FindHandle
#define FindResult 
#dim InnerMask[65536]
#define InnerMask[0] ""
#define size 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
            #define Public size size + FileSize(FileName)
        #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 RunSizeScan
    #define Public InnerMaskPosition 1
    #define Public InnerMaskWorkPosition 0
    #expr size=0
    #for {InnerMaskWorkPosition = 0; InnerMaskWorkPosition < InnerMaskPosition; InnerMaskWorkPosition++} ProcessInnerMaskPosition
    #undef Public InnerMaskPosition
    #undef Public InnerMaskWorkPosition
#endsub

#expr InnerMask[0]="some-dir-name-you-want-the-size-of\"
#expr RunSizeScan

#if size > 2100000000
    #define Span "True"
#else
    #define Span "False"
#endif

What it does is to scan the given directories in the array "InnerMask" for everything which isn't "." or "..". Files are added to the already calculated size and directories are added to the array "InnerMask". This Process will end once there are no more subdirectories to evaluate.

Note: As the limitation of the array is set to 65536, you should not have more than this amount of folders nested in you scanned directory. Otherwise you could try to reuse the first already processed array slots or work with multiple arrays.



回答2:

Here's the recursive version, broken into several macros for readability:

#define private CalcDirSize(str path, int size = 0) \
    CalcFileSize(path, FindFirst(AddBackSlash(path) + '*.*', faAnyFile), size)

#define private CalcFileSize(str path, int handle, int size) \
    handle ? CalcFileSizeFilterPath(path, handle, size) : size

#define private CalcFileSizeFilterPath(str path, int handle, int size) \
    FindGetFilename(handle) == '.' || FindGetFilename(handle) == '..' ? \
        GoToNextFile(path, handle, size) : \
        CalcFileSizeTestIfDir(path, handle, size, AddBackSlash(path) + FindGetFilename(handle))

#define private GoToNextFile(str path, int handle, int size) \
    FindNext(handle) ? CalcFileSizeFilterPath(path, handle, size) : size

#define private CalcFileSizeTestIfDir(str path, int handle, int size, str filename) \
    DirExists(filename) ? CalcDirSize(filename) + GoToNextFile(path, handle, size) : \
        GoToNextFile(path, handle, size + FileSize(filename))

Doesn't support too many files (poor ISPP will run out of memory) or large sizes (>2gb), but it should work well for smaller setups.