I have been trying to use the system calls GetFileVersionInfo and VerQueryValue to get the product version of an exe. I am using a legacy NSIS v2.0b3 (lots of scripts already in use and just wanting to make one little change).
After searching for a while I saw this solution Product version string from an exe - nsis ...but am having problems getting it to work sensibly.
The main call seems to work... ie
System::Call 'VERSION::GetFileVersionInfo(tr3,i,ir4,ir5)i.r0'
MessageBox MB_OK "GetFileVersionInfo returned dwLen=[$4] and lpData=[$5] for the block of Version Info"
...shows a sensible ptr in $5. The next call is where things go wrong...
System::Call 'VERSION::VerQueryValue(ir5,t"\",*i.r6,*i.r7)i.r0'
StrCmp $0 0 fail
MessageBox MB_OK "VS_FIXEDFILEINFO returned as lplpBuffer=[$6] and PUINT=[$7]"
This call returns 0,0 for $6 and $7. And then of course the parsing fails...
;;---Parse buffer at $6 (lplp)
System::Call '*$6(i,i,i,i,i.r2,i.r1)'
MessageBox MB_OK "Read data from struct @$6: skip 4 ints then ints are dwProductVersionMS:[$2] dwProductVersionLS:[$1]"
...returns 0,0.
I'm thinking the problem is the indirect pointer in $6 here. That is, $6 is type LPVOID *lplpBuffer ....so I think the syntax of the call to set the value of $6 may need to be different.
Any help welcome... I tried some variations without success.
===Following request posted, here is the latest of many variations I have tried... hopefully that will help clarify what I am doing===
Function GetDllProductVersion
; https://stackguides.com/questions/34616470/nsis-get-product-version?rq=1
; https://stackguides.com/questions/38707235/product-version-string-from-an-exe-nsis slightly different System::Call's, but also later nsis not compatible
;;System::Store S ;;;removed this and the matching Store L, as that crashes
Pop $3
;; System::Call 'VERSION::GetFileVersionInfoSize(tr3,*i)i.r4'
;; MessageBox MB_OK "GetFileVersionInfoSize gets size [$4]" ; cannot get a sensible answer, returns "error" in $4
;;---allocate block, address into $5
StrCpy $4 0
IntOp $4 $4 + 10000 ; set $4 to 10000
System::Call '*(&i$4,t""r1,t""r2)i.r5' ; Set $1 and $2 to "" so they are empty if we fail
MessageBox MB_OK "System::Call allocs [$4] bytes at addr [$5], next call GetFileVersionInfo"
StrCmp $4 0 fail
StrCmp $5 0 fail
;;---GetFileVersionInfo now-----
System::Call 'VERSION::GetFileVersionInfo(tr3,i,ir4,ir5)i.r0' ;; ir5 not isr5 ?? diff between solutions
StrCmp $0 0 fail
MessageBox MB_OK "GetFileVersionInfo returned dwLen=[$4] and lpData=[$5] for the block of Version Info"
;;---Now we get the VS_FIXEDFILEINFO structure using $5.... $6 will be lplpBuffer for it and $7 will be PUINT ptr to size of data in lplpBuffer
System::Call 'VERSION::VerQueryValue(ir5,t"\",*i.r6,*i.r7)i.r0' ;; using &i.r6 etc, not *i.r6 gives 0,0 no good, go back to *
StrCmp $0 0 fail
MessageBox MB_OK "VS_FIXEDFILEINFO returned as lplpBuffer=[$6] and PUINT=[$7]"
;;---Parse buffer at $6 (lplp)
System::Call '**$6(i,i,i,i,i.r2,i.r1)'
MessageBox MB_OK "Read data from struct @$6: skip 4 ints then ints are dwProductVersionMS:[$2] dwProductVersionLS:[$1]"
;;;or?????
System::Call '**$6(i,i,i,i,&i.r2,&i.r1)'
MessageBox MB_OK "Read data using & from struct @$6: skip 4 ints then ints are dwProductVersionMS:[$2] dwProductVersionLS:[$1]"
fail:
System::Free $5
MessageBox MB_OK "After System::Free [$5]"
Push $1
Push $2
;;System::Store L ;;;this crashes!!! so push and pop indiv registers used
FunctionEnd