【发布时间】:2018-11-30 06:31:59
【问题描述】:
我一直在尝试使用系统调用 GetFileVersionInfo 和 VerQueryValue 来获取 exe 的产品版本。我使用的是旧版 NSIS v2.0b3(很多脚本已经在使用,只是想做一点小改动)。
搜索了一段时间后,我看到了这个解决方案 Product version string from an exe - nsis ...但是在使其正常工作时遇到问题。
主要调用似乎有效......即
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"
...在 $5 中显示一个合理的 ptr。 下一个电话是出问题的地方......
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]"
此调用为 6 美元和 7 美元返回 0,0。然后当然解析失败了......
;;---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]"
...返回 0,0。
我认为问题在于 $6 中的间接指针。 也就是说,$6 是类型 LPVOID *lplpBuffer ....所以我认为设置 $6 值的调用的语法可能需要不同。
欢迎任何帮助...我尝试了一些变化但没有成功。
===以下请求已发布,这是我尝试过的许多变体中的最新版本...希望这将有助于澄清我在做什么===
Function GetDllProductVersion
; https://stackoverflow.com/questions/34616470/nsis-get-product-version?rq=1
; https://stackoverflow.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
【问题讨论】:
-
请确认您的 NSIS 版本。 2.0b3 于 2003 年发布!如果你不能使用 NSIS v3(为什么?),至少使用 v2.51。
-
你发布的代码和你喜欢的不一样。您应该发布您的完整代码,以便人们可以实际编译和测试您有问题的代码!
-
...发布更多代码。你在哪里分配 5 美元?如果你不能发布一个完整的功能,我不会费心去调查这个。
-
好的,将尝试发布我尝试过的最新版本...很多变化。使用 2.0b3 的原因是为了让解压缩时区独立而做了一个小编辑。我知道...可以将所有内容迁移到以后的 NSIS,但我认为这里的问题是调用返回 lplpBuffer ptr 的函数。
-
在我的时区凌晨 3 点之后...感谢您到目前为止的快速响应,我肯定会在 6 小时左右后重新上线...请转至 cmets,谢谢
标签: nsis