How do I retrieve the version of a file from a batch file on Windows Vista?

前端 未结 7 1059
傲寒
傲寒 2020-12-05 14:39

Binary files have a version embedded in them - easy to display in Windows Explorer.

\"alt

How can I re

相关标签:
7条回答
  • 2020-12-05 15:16

    Here is a solution in PowerShell using FileVersionInfo.

    0 讨论(0)
  • 2020-12-05 15:20

    I think filever is what you need. It can get the file version for multiple items at the same time and locate files (e.g. EXE, DLL) that differ in size or version number.

    0 讨论(0)
  • 2020-12-05 15:23

    The file version could be simply read without external tools by PowerShell like this:

    (Get-Item myFile.exe).VersionInfo.FileVersion
    

    and if you want to read it from an Batch file use:

    powershell -NoLogo -NoProfile -Command (Get-Item myFile.exe).VersionInfo.FileVersion
    

    and to save the file version to a variable use:

    FOR /F "USEBACKQ" %%F IN (`powershell -NoLogo -NoProfile -Command ^(Get-Item "myFile.exe"^).VersionInfo.FileVersion`) DO (SET fileVersion=%%F)
    echo File version: %fileVersion%
    

    I've taken a realtive path here, you could also define it absolutely, like: C:\myFile.dll

    More information about the file is shown if you omit .FileVersion

    0 讨论(0)
  • 2020-12-05 15:33

    and three ways without external tools

    1.WMIC

    WMIC DATAFILE WHERE name="C:\\install.exe" get Version /format:Textvaluelist
    

    Pay attention to the double slashes of file name.

    Ready to use script:

    @echo off
    :wmicVersion pathToBinary [variableToSaveTo]
    setlocal
    set "item=%~1"
    set "item=%item:\=\\%"
    
    
    for /f "usebackq delims=" %%a in (`"WMIC DATAFILE WHERE name='%item%' get Version /format:Textvaluelist"`) do (
        for /f "delims=" %%# in ("%%a") do set "%%#"
    )
    
    if "%~2" neq "" (
        endlocal & (
            echo %version%
            set %~2=%version%
        )
    ) else (
        echo %version%
    )
    

    2.MAKECAB as the WMIC is not installed on home versions of windows here's a way with makecab that will run on every windows machine:

    ; @echo off
    ;;goto :end_help
    ;;setlocal DsiableDelayedExpansion
    ;;;
    ;;;
    ;;; fileinf /l list of full file paths separated with ;
    ;;; fileinf /f text file with a list of files to be processed ( one on each line )
    ;;; fileinf /? prints the help
    ;;;
    ;;:end_help
    
    ; REM Creating a Newline variable (the two blank lines are required!)
    ; set NLM=^
    
    
    ; set NL=^^^%NLM%%NLM%^%NLM%%NLM%
    ; if "%~1" equ "/?" type "%~f0" | find ";;;" | find /v "find" && exit /b 0
    ; if "%~2" equ "" type "%~f0" | find ";;;" | find /v "find" && exit /b 0
    ; setlocal enableDelayedExpansion
    ; if "%~1" equ "/l" (
    ;  set "_files=%~2"
    ;  echo !_files:;=%NL%!>"%TEMP%\file.paths"
    ;  set _process_file="%TEMP%\file.paths"
    ;  goto :get_info
    ; )
    
    ; if "%~1" equ "/f" if exist "%~2" (
    ;  set _process_file="%~2"
    ;  goto :get_info
    ; )
    
    ; echo incorect parameters & exit /b 1
    ; :get_info
    ; set "file_info="
    
    ; makecab /d InfFileName=%TEMP%\file.inf /d "DiskDirectory1=%TEMP%" /f "%~f0"  /f %_process_file% /v0>nul
    
    ; for /f "usebackq skip=4 delims=" %%f in ("%TEMP%\file.inf") do (
    ;  set "file_info=%%f"
    ;  echo !file_info:,=%nl%!
    ; )
    
    ; endlocal
    ;endlocal
    ; del /q /f %TEMP%\file.inf 2>nul
    ; del /q /f %TEMP%\file.path 2>nul
    ; exit /b 0
    
    .set DoNotCopyFiles=on
    .set DestinationDir=;
    .set RptFileName=nul
    .set InfFooter=;
    .set InfHeader=;
    .Set ChecksumWidth=8
    .Set InfDiskLineFormat=;
    .Set Cabinet=off
    .Set Compress=off
    .Set GenerateInf=ON
    .Set InfDiskHeader=;
    .Set InfFileHeader=;
    .set InfCabinetHeader=;
    .Set InfFileLineFormat=",file:*file*,date:*date*,size:*size*,csum:*csum*,time:*time*,vern:*ver*,vers:*vers*,lang:*lang*"
    

    example output (it has a string version which is a small addition to wmic method :) ):

    c:> fileinfo.bat /l C:\install.exe
        file:install.exe
        date:11/07/07
        size:562688
        csum:380ef239
        time:07:03:18a
        vern:9.0.21022.8
        vers:9.0.21022.8 built by: RTM
        lang:1033
    

    3 Using shell.application and hybrid batch\jscript.Here's tooptipInfo.bat :

    @if (@X)==(@Y) @end /* JScript comment
        @echo off
    
        rem :: the first argument is the script name as it will be used for proper help message
        cscript //E:JScript //nologo "%~f0" %*
    
        exit /b %errorlevel%
    
    @if (@X)==(@Y) @end JScript comment */
    
    ////// 
    FSOObj = new ActiveXObject("Scripting.FileSystemObject");
    var ARGS = WScript.Arguments;
    if (ARGS.Length < 1 ) {
     WScript.Echo("No file passed");
     WScript.Quit(1);
    }
    var filename=ARGS.Item(0);
    var objShell=new ActiveXObject("Shell.Application");
    /////
    
    
    //fso
    ExistsItem = function (path) {
        return FSOObj.FolderExists(path)||FSOObj.FileExists(path);
    }
    
    getFullPath = function (path) {
        return FSOObj.GetAbsolutePathName(path);
    }
    //
    
    //paths
    getParent = function(path){
        var splitted=path.split("\\");
        var result="";
        for (var s=0;s<splitted.length-1;s++){
            if (s==0) {
                result=splitted[s];
            } else {
                result=result+"\\"+splitted[s];
            }
        }
        return result;
    }
    
    
    getName = function(path){
        var splitted=path.split("\\");
        return splitted[splitted.length-1];
    }
    //
    
    function main(){
        if (!ExistsItem(filename)) {
            WScript.Echo(filename + " does not exist");
            WScript.Quit(2);
        }
        var fullFilename=getFullPath(filename);
        var namespace=getParent(fullFilename);
        var name=getName(fullFilename);
        var objFolder=objShell.NameSpace(namespace);
        var objItem=objFolder.ParseName(name);
        //https://msdn.microsoft.com/en-us/library/windows/desktop/bb787870(v=vs.85).aspx
        WScript.Echo(fullFilename + " : ");
        WScript.Echo(objFolder.GetDetailsOf(objItem,-1));
    
    }
    
    main();
    

    used against cmd.exe :

    C:\Windows\System32\cmd.exe :
    File description: Windows Command Processor
    Company: Microsoft Corporation
    File version: 6.3.9600.16384
    Date created: ?22-?Aug-?13 ??13:03
    Size: 347 KB
    
    0 讨论(0)
  • 2020-12-05 15:35

    I've found this code from Rob Vanderwoude's site:

    @ECHO OFF
    IF [%1]==[] GOTO Syntax
    IF NOT [%2]==[] GOTO Syntax
    ECHO.%1 | FIND "?" >NUL
    IF NOT ERRORLEVEL 1 GOTO Syntax
    IF NOT EXIST %1 GOTO Syntax
    IF NOT "%OS%"=="Windows_NT" GOTO Syntax
    
    SETLOCAL
    SET FileVer=
    FOR /F "tokens=1 delims=[]" %%A IN ('STRINGS %1 ^| FIND /N /V "" ^| FIND /I "FileVersion"') DO SET LineNum=%%A
    SET /A LineNum += 1
    FOR /F "tokens=1* delims=[]" %%A IN ('STRINGS %1 ^| FIND /N /V "" ^| FIND "[%LineNum%]"') DO SET FileVer=%%B
    SET FileVer
    ENDLOCAL
    GOTO:EOF
    
    :Syntax
    ECHO.
    ECHO FileVer.bat,  Version 1.00 for NT 4 / 2000 / XP
    ECHO Display the specified file's version number
    ECHO.
    ECHO Usage:  FILEVER  progfile
    ECHO.
    ECHO Where:  "progfile" is the name of a Windows executable, DLL, or system file
    ECHO.
    ECHO Uses SysInternal's STRINGS.EXE, avalable at http://www.sysinternals.com
    ECHO.
    ECHO Written by Rob van der Woude
    ECHO http://www.robvanderwoude.com
    

    Looks interesting as it uses STRINGS from SysInternals.

    0 讨论(0)
  • 2020-12-05 15:37

    Here is my try using WMIC to get file version of all *.exe and *.dll inside the directory of Skype as example :

    @echo off
    Mode 75,3 & color 9E
    Title Get File Version of any Program from file list using WMIC by Hackoo
    Set "RootFolder=%ProgramFiles%\Skype"
    @for %%a in (%RootFolder%) do set "FolderName=%%~na"
    Set "File_Version_List=%~dp0%FolderName%_File_Version_List.txt"
    Set "ErrorFile=%~dp0%FolderName%_Error.txt
    Set Extensions="*.exe" "*.dll"
    If exist "%ErrorFile%" Del "%ErrorFile%"
    If exist "%File_Version_List%" Del "%File_Version_List%"
    echo(
    echo          Please wait a while ... Process to get file version ...
    set "BuildLineWith=call :BuildLine "
    setlocal enabledelayedexpansion
    CD /D "%RootFolder%"
    @for /f "delims=" %%F in ('Dir /b /s %Extensions%') do (
        set "Version="
        Call :Get_AppName "%%F" AppName
        Call :Add_backSlash "%%F"
        Call :GetVersion !Application! Version
        Call :Remove_backSlash !Application!
        If defined Version (
            (
                echo !Application!
                echo !AppName! ==^> !Version!
                %BuildLineWith%*
            )>> "%File_Version_List%"
        ) else (
            (
                echo Version is not defined in !Application!
                %BuildLineWith%#
            )>> "%ErrorFile%"
        )
    )
    If Exist "%ErrorFile%" Start "" "%ErrorFile%"
    If Exist "%File_Version_List%" Start "" /MAX "%File_Version_List%" & Exit
    ::*******************************************************************
    :GetVersion <ApplicationPath> <Version>
    Rem The argument %~1 represente the full path of the application
    Rem without the double quotes
    Rem The argument %2 represente the variable to be set (in our case %2=Version)  
    FOR /F "tokens=2 delims==" %%I IN (
      'wmic datafile where "name='%~1'" get version /format:Textvaluelist 2^>^nul'
    ) DO FOR /F "delims=" %%A IN ("%%I") DO SET "%2=%%A"
    Exit /b
    ::*******************************************************************
    :Add_backSlash <String>
    Rem Subroutine to replace the simple "\" by a double "\\" into a String
    Set "Application=%1"
    Set "String=\"
    Set "NewString=\\"
    Call Set "Application=%%Application:%String%=%NewString%%%"
    Exit /b
    ::*******************************************************************
    :Remove_backSlash <String>
    Rem Subroutine to replace the double "\\" by a simple "\" into a String
    Set "Application=%1"
    Set "String=\\"
    Set "NewString=\"
    Call Set "Application=%%Application:%String%=%NewString%%%"
    Exit /b
    ::*******************************************************************
    :Get_AppName <FullPath> <AppName>
    Rem %1 = FullPath
    Rem %2 = AppName
    for %%i in (%1) do set "%2=%%~nxi"
    exit /b
    ::*******************************************************************
    :BuildLine
    set "LineChar=%1"
    if "%LineChar%"=="" set "LineChar=_"
    for /f "tokens=2 skip=4" %%A in ('mode con: /status') do set "WindowColumns=%%A" & goto :GotColumnCount
    :GotColumnCount
    set "CharLine="
    setlocal EnableDelayedExpansion
    for /L %%A in (1,1,%WindowColumns%) do set "CharLine=!CharLine!!LineChar:~0,1!"
    setlocal DisableDelayedExpansion
    endlocal
    echo %CharLine%
    goto :eof
    ::*******************************************************************
    
    0 讨论(0)
提交回复
热议问题