Do not include duplicate files multiple times in the Inno Setup installer

后端 未结 2 1360
执笔经年
执笔经年 2020-12-06 23:21

Can the size of my installer be reduced?

At the moment I have this code for my GoogleAuthAndSync support utility:

; Google Calendar Interface v3
Sour         


        
相关标签:
2条回答
  • 2020-12-06 23:46

    You can use preprocessor to iterate the DLL files in the subfolder and compare them against files in the base folder. If they match, use the file in the base folder as a source. Inno Setup will compile a source file only once to the installer, when used multiple times.

    The code is somewhat complicated by your use of SourceDir directive (of which the preprocessor is obviously not aware). Without the directive, the code would be simpler.

    [Files]
    #pragma parseroption -p-
    
    #define FileEntry(Source, DestPath) \
        "Source: " + Source + "; DestDir: " + DestPath + "\n"
    
    #define GetFileTimestamp(Path) GetFileDateTimeString(Path, 'dd/mm/yyyy hh:nn:ss', '-', ':')
    
    #define ProcessFile(RootPath, Path, AlternativePath, DestPath, FindResult, FindHandle) \
        FindResult ? \
            Local[0] = FindGetFileName(FindHandle), \
            Local[1] = AddBackslash(Path) + Local[0], \
            Local[2] = AddBackslash(AlternativePath) + Local[0], \
            Local[3] = AddBackslash(RootPath) + Local[1], \
            Local[4] = AddBackslash(RootPath) + Local[2], \
            Local[5] = \
               FileExists(Local[4]) && \
               (GetFileTimestamp(Local[3]) == GetFileTimestamp(Local[4])), \
            FileEntry((Local[5] ? Local[2] : Local[1]), DestPath) + \
            ProcessFile(RootPath, Path, AlternativePath, DestPath, \
                FindNext(FindHandle), FindHandle) \
        : ""
    
    #define ProcessFolderWithAlternativeSource(RootPath, Path, AlternativePath, DestPath) \
        Local[0] = FindFirst(AddBackslash(AddBackslash(RootPath) + Path) + "*.dll", 0), \
        ProcessFile(RootPath, Path, AlternativePath, DestPath, Local[0], Local[0])
    
    #pragma parseroption -p+
    
    #emit ProcessFolderWithAlternativeSource( \
        "..\Meeting Schedule Assistant\Release", "OutlookCalIFConsole", ".", \
        "{app}\OutlookCalIFConsole")
    

    Or you can use SetupSetting to read the SourceDir directive:

    #emit ProcessFolderWithAlternativeSource( \
        SetupSetting("SourceDir"), "OutlookCalIFConsole", ".", "{app}\OutlookCalIFConsole")
    

    If you add SaveToFile to the end of the script:

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

    ... then you should see something like this, in the Preprocessed.iss:

    [Files]
    Source: OutlookCalIFConsole\CommandLine.dll; Dest: {app}\OutlookCalIFConsole
    Source: OutlookCalIFConsole\Microsoft.Graph.Core.dll; Dest: {app}\OutlookCalIFConsole
    Source: OutlookCalIFConsole\Microsoft.Graph.dll; Dest: {app}\OutlookCalIFConsole
    Source: OutlookCalIFConsole\Microsoft.Identity.Client.dll; Dest: {app}\OutlookCalIFConsole
    Source: .\Newtonsoft.Json.dll; Dest: {app}\OutlookCalIFConsole
    Source: OutlookCalIFConsole\System.Console.dll; Dest: {app}\OutlookCalIFConsole
    Source: OutlookCalIFConsole\System.IO.dll; Dest: {app}\OutlookCalIFConsole
    Source: .\System.Net.Http.dll; Dest: {app}\OutlookCalIFConsole
    Source: OutlookCalIFConsole\System.Reflection.dll; Dest: {app}\OutlookCalIFConsole
    Source: OutlookCalIFConsole\System.Reflection.TypeExtensions.dll; Dest: {app}\OutlookCalIFConsole
    Source: OutlookCalIFConsole\System.Runtime.dll; Dest: {app}\OutlookCalIFConsole
    Source: OutlookCalIFConsole\System.Runtime.Extensions.dll; Dest: {app}\OutlookCalIFConsole
    Source: .\System.Security.Cryptography.Algorithms.dll; Dest: {app}\OutlookCalIFConsole
    Source: .\System.Security.Cryptography.Encoding.dll; Dest: {app}\OutlookCalIFConsole
    Source: .\System.Security.Cryptography.Primitives.dll; Dest: {app}\OutlookCalIFConsole
    Source: .\System.Security.Cryptography.X509Certificates.dll; Dest: {app}\OutlookCalIFConsole
    

    Note the entries for Newtonsoft.Json.dll, System.Net.Http.dll and System.Security.Cryptography.*.


    Instead of comparing the files by GetFileDateTimeString (indirectly via GetFileDateTimeString), you can also use GetFileVersion (as the files are DLLs).

    If you need additional parameters in the [Files] section entries, modify FileEntry macro accordingly.

    0 讨论(0)
  • 2020-12-06 23:57

    I found the solution that allows InnoSetup compiler to succesfully deduplicate files during compression, the intrested part of my config is:

    Compression=lzma2/ultra64
    LZMANumBlockThreads=4
    CompressionThreads=4
    LZMADictionarySize=262144 ; this allows to find duplicated files and succesfully deduplicate them (but compressor consumes up to 2.5GB / ram during compilation)
    LZMAUseSeparateProcess=yes
    SolidCompression=yes
    

    InnoSetup version is 6.0.2 (u)

    0 讨论(0)
提交回复
热议问题