Jump to content

VBScript to retrieve the Version info from an EXE


Recommended Posts

Good Work Gary! :D

What a compliment to the script.

Link to comment
Share on other sites

Good Work Gary! :D

What a compliment to the script.

Thanks, but I found a problem with doing it that way, even microsoft don't conform to that.

looking into

http://msdn.microsoft.com/library/en-us/wi...versioninfo.asp

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

here's what I have so far on a different option

Func OnAutoItStart()
    ;uncomment this for drag to or commandline usage.
    If $CmdLine[0] = 0 Then
        MsgBox(266288, @ScriptName, "Drop A PE file [EXE-DLL-OCX] onto this script to get version information." & _
                @CRLF & "Commad Prompt Usage:" & @CRLF & @ScriptName & " " & "myfile.[exe,dll,ocx]")
        Exit
    EndIf
    Global $Arg = $CmdLine[1]
    Local $v_ret = DllCall("version.dll","int","GetFileVersionInfoSize","str", $Arg, "int", 0)
    If @error Or Not IsArray($v_ret) Then Exit
    Local $dwlen = $v_ret[0]
    $struct = DllStructCreate("char[" & $dwlen & "]")
    $v_ret = DllCall("version.dll","int","GetFileVersionInfo","str",$Arg,"int",0, "int", $dwlen, "ptr", DllStructGetPtr($struct))
    If @error Or Not IsArray($v_ret) Then Exit
    If Not $v_ret[0] Then Exit
;**********************************************************************
; this section might be wrong *************************************
;**********************************************************************
    $struct2 = DllStructCreate("ptr")
    $struct3 = DllStructCreate("int")
    $v_ret = DllCall("version.dll","int","VerQueryValue","ptr",DllStructGetPtr($struct),"str","", "ptr", DllStructGetPtr($struct2), "ptr", DllStructGetPtr($struct3))
    ConsoleWrite(DllStructGetData($struct3,1) & @LF)
;**********************************************************************
    Exit
    _Main()
EndFunc   ;==>OnAutoItStart

close to the end of the day, and i'm starting to brain fart

here's a link to the info for the last part

http://msdn.microsoft.com/library/en-us/wi...ingfileinfo.asp

Nested structs

http://msdn.microsoft.com/library/default......../string.asp\

Link to comment
Share on other sites

here's what I have so far on a different option

Func OnAutoItStart()
    ;uncomment this for drag to or commandline usage.
    If $CmdLine[0] = 0 Then
        MsgBox(266288, @ScriptName, "Drop A PE file [EXE-DLL-OCX] onto this script to get version information." & _
                @CRLF & "Commad Prompt Usage:" & @CRLF & @ScriptName & " " & "myfile.[exe,dll,ocx]")
        Exit
    EndIf
    Global $Arg = $CmdLine[1]
    Local $v_ret = DllCall("version.dll","int","GetFileVersionInfoSize","str", $Arg, "int", 0)
    If @error Or Not IsArray($v_ret) Then Exit
    Local $dwlen = $v_ret[0]
    $struct = DllStructCreate("char[" & $dwlen & "]")
    $v_ret = DllCall("version.dll","int","GetFileVersionInfo","str",$Arg,"int",0, "int", $dwlen, "ptr", DllStructGetPtr($struct))
    If @error Or Not IsArray($v_ret) Then Exit
    If Not $v_ret[0] Then Exit
;**********************************************************************
; this section might be wrong *************************************
;**********************************************************************
    $struct2 = DllStructCreate("ptr")
    $struct3 = DllStructCreate("int")
    $v_ret = DllCall("version.dll","int","VerQueryValue","ptr",DllStructGetPtr($struct),"str","\", "ptr", DllStructGetPtr($struct2), "ptr", DllStructGetPtr($struct3))
    ConsoleWrite(DllStructGetData($struct3,1) & @LF)
;**********************************************************************
    Exit
    _Main()
EndFunc   ;==>OnAutoItStart

close to the end of the day, and i'm starting to brain fart

here's a link to the info for the last part

http://msdn.microsoft.com/library/en-us/wi...rqueryvalue.asp

Edit: corrected link

Edited by gafrost

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

Looks like mike got what he needed in the earlier versions.

I'm hoping to be able to get more out of the file info being i'm in patch management and a few other things that it would come in handy for.

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

Looks like mike got what he needed in the earlier versions.

Agreed.

Link to comment
Share on other sites

Func OnAutoItStart()
    ;uncomment this for drag to or commandline usage.
    If $CmdLine[0] = 0 Then
        MsgBox(266288, @ScriptName, "Drop A PE file [EXE-DLL-OCX] onto this script to get version information." & _
                @CRLF & "Commad Prompt Usage:" & @CRLF & @ScriptName & " " & "myfile.[exe,dll,ocx]")
        Exit
    EndIf


EndFunc   ;==>OnAutoItStart
    Global $Arg = $CmdLine[1]

    GetInfo($Arg)
    Exit

Func GetInfo($sFile)
    if Not(FileExists($sFile)) then Exit
        Local $FI ="int;int;int;int;int;int;int;int;int;int;int;int;int"
        Local $v_ret = DllCall("version.dll","int","GetFileVersionInfoSize","str", $sFile, "int", 0)
        If @error Or Not IsArray($v_ret) Then Exit
        
        Local $dwlen = $v_ret[0]
        if $dwlen > 0 then 
            Local $Buffer = DllStructCreate("char["&$dwlen&"]")
        Local    $v_ret = DllCall("version.dll","int","GetFileVersionInfo","str",$sFile,"int",0, "int", $dwlen, "ptr", DllStructGetPtr($Buffer,1))
            ConsoleWrite("Point 1" & @LF)
            if @error or Not(IsArray($v_ret)) then Exit
                
            Local    $lpBuffer = DllStructCreate("int")
            Local    $nSize = DllStructCreate("int")
                $v_ret =  DllCall("version.dll","int","VerQueryValue","ptr", DllStructGetPtr($Buffer,1), "str","\", "int", DllStructGetPtr($lpBuffer), "int", DllStructGetPtr($nSize))
                ConsoleWrite("Point 2" & @LF)
                if @error or Not(IsArray($v_ret)) then Exit
                ConsoleWrite( DllStructGetData($lpBuffer,1)& @LF)
                
                Local    $FileInfo = DllStructCreate($FI)
                    $v_ret = DllCall("kernel32.dll","none","CopyMemory","ptr",DllStructGetPtr($FileInfo),"ptr",DllStructGetData($lpBuffer,1),"int",DllStructGetSize($FileInfo))
                    ConsoleWrite("Point 3" & @LF)
                    ;if @error or Not(IsArray($v_ret)) Then Exit
                    if @error then Exit
                    ConsoleWrite(DllStructGetData($FileInfo,1) & @LF)
                    
                $v_ret =  DllCall("version.dll","int","VerQueryValue","ptr", DllStructGetPtr($Buffer,1), "str","\VarFileInfo\Translation", "int", DllStructGetPtr($lpBuffer), "int", DllStructGetPtr($nSize))
                ConsoleWrite("Point 4" & @LF)
                if @error or Not(IsArray($v_ret)) then Exit
                    if $v_ret[0] Then
                        Local $sTmpVer
                        $sTmpVer = GetStringFromPtr( DllStructGetData($lpBuffer,1))
                        ConsoleWrite("$sTmpVer= "& $sTmpVer&@LF)
                    EndIf
        EndIf
                
EndFunc

Func GetStringFromPtr($ptr)
    Local $ret
    local $v_len = DllCall("kernel32","int","lstrlenA","ptr",$ptr)
    if @error or Not(IsArray($v_len)) then Return 0
    $ret = _String($v_len[0],Chr(0))
    $st_ret =DllStructCreate("char["&$v_len[0]&"]")
    DllStructSetData($st_ret,1,$ret)
    Local $v_ret =DllCall("kernel32","int","lstrcpyA","ptr", DllStructGetPtr($st_ret), "ptr",$ptr)
    if @error or Not(IsArray($v_ret)) then Return 0
    Return DllStructGetData($st_ret,1)
EndFunc
    
Func _String($iNumber,$sChar,$flag =0 )
    ;mimic VB String func. VB uses first char only
    ;This has a flag that defaults to single char
    ;When set to 1 is will repeat the complete string.
    Local $sTemp
    For $x = 1 to $iNumber
        if $flag =0 Then $sTemp = $sTemp & Stringleft($sChar,1)
        if $flag =1 then $sTemp = $sTemp & $sChar
    Next
    Return $sTemp
EndFunc

I got pointers but can't get the data. :D

Link to comment
Share on other sites

I got it working with api calls, at least for FileVersion.

Func OnAutoItStart()
    ;uncomment this for drag to or commandline usage.
    If $CmdLine[0] = 0 Then
        MsgBox(266288, @ScriptName, "Drop A PE file [EXE-DLL-OCX] onto this script to get version information." & _
                @CRLF & "Commad Prompt Usage:" & @CRLF & @ScriptName & " " & "myfile.[exe,dll,ocx]")
        Exit
    EndIf


EndFunc   ;==>OnAutoItStart
    Global $Arg = $CmdLine[1]
;    MsgBox(64 ,"AddressFor Arg", AddressFor($Arg))
    GetInfo($Arg)
    Exit

Func GetInfo($sFile)
        if Not(FileExists($sFile)) then Exit
        Local $FI ="int;int;int;int;int;int;int;int;int;int;int;int;int"
        Local $v_ret = DllCall("version.dll","int","GetFileVersionInfoSize","str", $sFile, "int", 0)
        If @error Or Not IsArray($v_ret) Then Exit
            ConsoleWrite("GetFileVersionInfoSize =" &$v_ret[0]& @LF)
        
        Local $dwlen = $v_ret[0]
        if $dwlen <= 0 then Exit ;no len the no info
            ConsoleWrite("GetFileVersionInfoSize = " & $dwlen & @LF)
        
        Local $resBlock = DllStructCreate("byte["&$dwlen&"]") ; resource block
        Local    $v_ret = DllCall("version.dll","int","GetFileVersionInfo","str",$sFile,"int",0, "int", $dwlen, "ptr", DllStructGetPtr($resBlock))
        ; greater than 0 for success
        ConsoleWrite("GetFileVersionInfo "&$v_ret[0] & @LF)
        if @error or Not(IsArray($v_ret)) then Exit
            
        Local $Ver = "\StringFileInfo\040904B0\FileVersion"
;        Local $Ver ="\"
            Local    $lpBuffer = DllStructCreate("int");recv pointer to pointer for data
            Local    $nSize = DllStructCreate("int"); rev pointer to size in char of data
            $v_ret =  DllCall("version.dll","int","VerQueryValue","ptr", DllStructGetPtr($resBlock), "str",$Ver, "ptr", DllStructGetPtr($lpBuffer), "int", DllStructGetPtr($nSize))
                ConsoleWrite("VerQueryValue Return Code="& $v_ret[0] & @LF )
                if @error or Not(IsArray($v_ret)) then Exit
                ; $v_ret[0] >0 = success.
                Local    $struct = DllStructCreate("int",DllStructGetData($lpBuffer,1))
                Local    $FileInfo = DllStructCreate("char["&DllStructGetData($nSize,1)&"]",DllStructGetData($lpBuffer,1))
                    ConsoleWrite("$struct="&$struct&@LF)
                    ConsoleWrite("$nSize ="& DllStructGetData($nSize,1) & @LF)
                    ConsoleWrite("Point 4" & @LF)
                    $sFileInfo = DllStructGetData($FileInfo,1)
                    ConsoleWrite("$sFileInfo = "&$sFileInfo&@LF)
EndFunc


Func _String($iNumber,$sChar,$flag =0 )
    ;mimic VB String func. VB uses first char only
    ;This has a flag that defaults to single char
    ;When set to 1 is will repeat the complete string.
    Local $sTemp
    For $x = 1 to $iNumber
        if $flag =0 Then $sTemp = $sTemp & Stringleft($sChar,1)
        if $flag =1 then $sTemp = $sTemp & $sChar
    Next
    Return $sTemp
EndFunc

Func AddressOf(ByRef $Variable)
    ;Get the address of a variable
    $v_ret = DllCall("apigid32.dll","int","agGetAddressForObject","str",$Variable)
    If @error Or Not IsArray($v_ret) Then Exit
    ConsoleWrite("AddressFor =" &$v_ret[0]& @LF)
    Return $v_ret[0]
EndFunc
Link to comment
Share on other sites

Ok, here it is. It's quite a bit smaller than the non api version. It doesn't produce results on some dll's where as the non-api version does. There may be a need to try DLLGetVersion. I'll investigate when I get some more time.

;Get FileVersion Info
;Version 0.0.0.2
;Authors:    Steve Podhajecki, Gary Frost    -- Thanks to MikeOsdx
#include <Array.au3>
#Region Compiler directives section
;** This is a list of compiler directives used by CompileAU3.exe.
;** comment the lines you don't need or else it will override the default settings
;#Compiler_Prompt=y                                  ;y=show compile menu
;** AUT2EXE settings
;#Compiler_AUT2EXE=
;#Compiler_Icon=au3.ico                              ;Filename of the Ico file to use
;#Compiler_OutFile=                                  ;Target exe filename.
#Compiler_Compression=4                             ;Compression parameter 0-4  0=Low 2=normal 4=High
#Compiler_Allow_Decompile=n                          ;y= allow decompile
;#Compiler_PassPhrase=                               ;Password to use for compilation
;** Target program Resource info
#Compiler_Res_Comment=Get [exe, dll, ocx] File Version(2) Info. Thanks To MikeOsdx 
#Compiler_Res_Description=File Version Information
#Compiler_Res_FileVersion_AutoIncrement=n
#Compiler_Res_Fileversion=0.0.0.2
#Compiler_Res_LegalCopyright= spodhajecki,gafrost
; free form resource fields ... max 15
#Compiler_Res_Field=Email|    ;Free format fieldname|fieldvalue
#Compiler_Res_Field=Release Date|07/21/2006          ;Free format fieldname|fieldvalue
#Compiler_Res_Field=Update Date|                    ;Free format fieldname|fieldvalue
#Compiler_Res_Field=Internal Name|FileProp2.exe    ;Free format fieldname|fieldvalue
#Compiler_Res_Field=Status|Beta                     ;Free format fieldname|fieldvalue
#Compiler_Run_AU3Check=y                            ;Run au3check before compilation
#Compiler_AU3Check_Dat= ;Override the default au3check definition
#Compiler_AU3Check_Parameters= -q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w 7 ;Au3Check parameters
;#Compiler_PlugIn_Funcs=
; The following directives can contain:
;   %in% , %out%, %icon% which will be replaced by the fullpath\filename.
;   %scriptdir% same as @ScriptDir and %scriptfile% = filename without extension.
#Compiler_Run_Before=                               ;process to run before compilation - you can have multiple records that will be processed in sequence
#Compiler_Run_After=move "%out%" "%scriptdir%"      ;process to run After compilation - you can have multiple records that will be processed in sequence
#EndRegion
#NoTrayIcon

;~ ;FileVersion 0.0.0.2
Global $Arg = $CmdLine[1], $DEBUG = False
Global $props[26] = [ "Signature", "StrucVersion", "ProductVersion", "FileFlagsMask", "FileFlags", "FileOS", "FileType", "FileDate", "CompanyName", "FileDescription", "FileVersion", "ProductName", "LegalCopyright", _
        "OriginalFilename", "Installer Engine", "Applies to", "Build Date", "Installation Type", _
        "Installer Version", "InternalName", "KB Article Number", "Support Link", "Package Type", _
        "Proc. Architecture", "Self-Extractor Version", "DisplayName"]
Main()
Exit

Func OnAutoItStart()
    ;uncomment this block for drag to or commandline usage.
    If $CmdLine[0] = 0 Then
        MsgBox(266288, @ScriptName, "Drop A PE file [EXE-DLL-OCX] onto this script to get version information." & _
                @CRLF & "Commad Prompt Usage:" & @CRLF & @ScriptName & " " & "myfile.[exe,dll,ocx]")
        Exit
    EndIf
EndFunc   ;==>OnAutoItStart

Func Main()
;    MsgBox(64 ,"AddressFor Arg", AddressFor($Arg))
;$Arg = "Windows2000-KB914388-x86-ENU.EXE"
;$Arg= "C:\WINDOWS\SYSTEM32\cmdhere.dll"
;$Arg ="C:\WINDOWS\SYSTEM32\comdlg32.dll"
;$Arg = "C:\WINDOWS\SYSTEM32\ZlibTool.ocx"
;$Arg = "C:\WINDOWS\SYSTEM32\Calc.exe"
Local $AReturn = GetInfo($Arg, $props)
If IsArray($AReturn) Then
    Local $s = ""
    For $x = 0 To UBound($props) - 1
        $s &= $props[$x] & ": " & Chr(9) & $AReturn[$x] & @CRLF
    Next
    MsgBox(266288, @ScriptName, $Arg & @CRLF & @CRLF & $s)
Else
    MsgBox(266288, "Error", "Information not found.")
EndIf
EndFunc

;===============================================================================
; Function Name:    GetInfo
; Description:        Get File version information from file string table.
; Parameter(s):        $sFile     File to get properties from
;                    $aProps     Name of file property to get
; Requirement(s):    Beta
; Return Value(s):    0 or array of propery values
; User CallTip:    
; Author(s):        Steve Podhajecki, Gary Frost.
; Note(s):            Does not work on some dll's
;===============================================================================
Func GetInfo($sFile, $aProps)
    If Not (FileExists($sFile)) Then
        SetError(1)
        Return 0
    EndIf
    
    Local $v_ret = DllCall("version.dll", "int", "GetFileVersionInfoSize", "str", $sFile, "int", 0)
    If @error Or Not IsArray($v_ret) Then
        SetError(2)
        Return 0
    EndIf
    Local $dwlen = $v_ret[0]
    If $dwlen <= 0 Then
        SetError(3)
        Return 0 ;no len the no info
    EndIf
    
    Local $resBlock = DllStructCreate("byte[" & $dwlen & "]") ; resource block
    $v_ret = DllCall("version.dll", "int", "GetFileVersionInfo", "str", $sFile, "int", 0, "int", $dwlen, "ptr", DllStructGetPtr($resBlock))
    ; greater than 0 for success
    If @error Or Not IsArray($v_ret) Then
        SetError(4)
        Return 0
    EndIf
    Local $aPropValues[UBound($aProps) ]
    Local    $lpBuffer = DllStructCreate("int");recv pointer to pointer for data
    Local    $nSize = DllStructCreate("int"); recv pointer to size in char of data
    Local $Ver
;~         If StringRight($sFile,4) = ".dll" Then
;~         $subBlock ="\"
;~         Else
    Local $subBlock = "\StringFileInfo\040904B0\"
;~         EndIf
    
    For $x = 0 To UBound($aProps) - 1
        $Ver = $subBlock & $aProps[$x]
        ;        Local $Ver ="\"
        $v_ret = DllCall("version.dll", "int", "VerQueryValue", "ptr", DllStructGetPtr($resBlock), "str", $Ver, "ptr", DllStructGetPtr($lpBuffer), "int", DllStructGetPtr($nSize))
        ; $v_ret[0] >0 = success.
        If @error Or Not (IsArray($v_ret)) Then
            SetError(6)
            Return 0
        EndIf
        
        if $DEBUG then ConsoleWrite("VerQueryValue Return Code="& $v_ret[0] & @LF )

        If $v_ret[0] > 0 Then
            Local    $FileInfo = DllStructCreate("char[" & DllStructGetData($nSize, 1) & "]", DllStructGetData($lpBuffer, 1))
            Local $sFileInfo = DllStructGetData($FileInfo, 1)
            $aPropValues[$x] = $sFileInfo
            $FileInfo = 0
        Else
            $aPropValues[$x] = ""
        EndIf
        
    Next
    Return $aPropValues
EndFunc   ;==>GetInfo

eltorro

Edit: cleaned code.

Edited by eltorro
Link to comment
Share on other sites

  • 4 weeks later...

If I remember correctly, I believe that is the codepage. So yes it has something to do with locale.

Link to comment
Share on other sites

  • 1 month later...

How i get the Codepage with this adding the upper code?

;Get Codepage
    Local $codepageBlock ="\VarFileInfo\Translation"
    $v_ret = DllCall("version.dll", "int", "VerQueryValue", "ptr", DllStructGetPtr($resBlock), "str", $codepageBlock, "ptr", DllStructGetPtr($lpBuffer), "int", DllStructGetPtr($nSize))
        If @error Or Not (IsArray($v_ret)) Then
            SetError(6)
            Return 0
        EndIf
    If $v_ret[0] > 0 Then
            Local $FileInfo = DllStructCreate("char[" & DllStructGetData($nSize, 1) & "]", DllStructGetData($lpBuffer, 1))
            Local $sFileInfo = DllStructGetData($FileInfo, 1)
        MsgBox(0,"the language? codepage?",$sFileInfo)
            $FileInfo = 0
        Else
        SetError(6)
        Return 0
    EndIf

Here comes only not useable things.

In my exe files is after the \VarFileInfo\Translation

in german files in hex 00 00 00 00 07 04 B0 04

and in english files in hex 00 00 00 00 09 04 B0 04

Can somebody me help?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...