English 中文(简体)
How do I retrieve the version of a file from a batch file on Windows Vista?
原标题:

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

alt text

How can I retrieve that file version, from a batch file?

最佳回答

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 batchjscript.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:WindowsSystem32cmd.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
问题回答

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

Check out sigcheck.exe from Sysinternals Suite. This is a command-line utility that shows file version number, timestamp information, and digital signature details.

Here is a solution in PowerShell using FileVersionInfo.

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.

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
::*******************************************************************

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.





相关问题
How does Vistalizer work

How does Vistalizer manage to override the language limit in Windows Vista Home edition. Which api s does it use to allow installation of Multiple language packages.

Ericsson f3507g WWAN (3G Broadband) and AT commands

I have a lenovo x200t tablet with WWAN built into it. I m trying to connect to the internet using AT commands and a C# program which I am making so that the program can connect to the net and upload ...

Correct place to install demostration projects?

With the new Windows 7 restrictions (well, new to Windows Vista anyways), we can no longer install demo projects to %ProgramFilesFolder%OurApplicationdemo since restricted users will not be able to ...

How Can I Check To See If the User Set His Clock Back?

In my desktop program, I want to check that to see if the user has set his clock back. To do so, I compare the timestamp of certain Operating System files to the current computer date. If any are ...

Vista/Win7 Listview "View Slider"

In Vista and Windows 7 almost any time the system uses a standard Listview (ie: Explorer Windows) it s accompanied by a little split button that shows a slider when the split is clicked that allows ...

热门标签