Search code examples
nsis

Product version string from an exe - nsis


I want to read the product version (optional string) from a given executable (actually from the installer I'm trying to create if it makes any difference), if it is possible at the run-time. This string will be further used to download files from a link.

Thank you very much !


Solution

  • NSIS does not have native support for reading anything other than VS_FIXEDFILEINFO->dwFileVersion so you have to call the Windows API directly:

    ; Add some version information so we have something to test
    VIProductVersion 1.2.3.4
    VIAddVersionKey "ProductVersion" "One Two Three Four"
    VIAddVersionKey "FileVersion" "Whatever"
    VIAddVersionKey "FileDescription" "Whatever"
    VIAddVersionKey "LegalCopyright" "(C) Whatever"
    
    !include LogicLib.nsh
    Function GetFileVerFirstLangProductVersion
    System::Store S
    pop $3
    push "" ;failed ret
    System::Call 'version::GetFileVersionInfoSize(t"$3",i.r2)i.r0'
    ${If} $0 <> 0
        System::Alloc $0
        System::Call 'version::GetFileVersionInfo(t"$3",ir2,ir0,isr1)i.r0 ? e'
        pop $2
        ${If} $0 <> 0
        ${AndIf} $2 = 0 ;a user comment on MSDN said you should check GLE to avoid crash
            System::Call 'version::VerQueryValue(i r1,t "\VarFileInfo\Translation",*i0r2,*i0)i.r0'
            ${If} $0 <> 0
                System::Call '*$2(&i2.r2,&i2.r3)'
                IntFmt $2 %04x $2
                IntFmt $3 %04x $3
                System::Call 'version::VerQueryValue(i r1,t "\StringFileInfo\$2$3\ProductVersion",*i0r2,*i0r3)i.r0'
                ${If} $0 <> 0
                    pop $0
                    System::Call *$2(&t$3.s)
                ${EndIf}
            ${EndIf}
        ${EndIf}
        System::Free $1
    ${EndIf}
    System::Store L
    FunctionEnd
    
    Section
    Push "$ExePath" ; Read our own version information in this example
    Call GetFileVerFirstLangProductVersion
    Pop $0
    DetailPrint "ProductVersion=$0"
    SectionEnd