2009-11-10 14 views
9

Los archivos binarios tienen una versión incrustada en ellos, fácil de visualizar en el Explorador de Windows.¿Cómo recupero la versión de un archivo de un archivo por lotes en Windows Vista?

alt text

¿Cómo puedo recuperar esa versión del archivo, desde un archivo por lotes?

+0

Ver http://stackoverflow.com/questions/602802/command-line- tool-to-dump-windows-dll-version – Helen

+0

¿Algún consejo aquí? [http://www.winvistatips.com/determine-version-exe-thru-batch-file-t284289.html](http://www.winvistatips.com/determine-version-exe-thru-batch-file -t284289.html) –

Respuesta

4

Creo que filever es lo que necesita. Puede obtener la versión del archivo para varios elementos al mismo tiempo y ubicar los archivos (por ejemplo, EXE, DLL) que difieren en tamaño o número de versión.

+4

Esto no está instalado de manera predeterminada. – macetw

+0

Nunca lo dije, y el enlace es un enlace de descarga .. –

+0

Eso funciona muy bien para 32 bits pero no parece manejar archivos de 64 bits –

6

Echa un vistazo sigcheck.exe de Sysinternals Suite. Esta es una utilidad de línea de comandos que muestra el número de versión del archivo, la información de la marca de tiempo y los detalles de la firma digital.

+0

Filever no será compatible de acuerdo con MSDN en los sistemas operativos Windows más nuevos, así que gracias . – AnneTheAgile

15

y tres maneras sin herramientas externas

1. WMIC

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

Prestar atención a las dobles barras de nombre de archivo.

Listo para el uso de la escritura:

@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 como el WMIC no está instalado en las versiones caseras de ventanas Aquí está una manera con makecab que se ejecutará en todas las máquinas de las ventanas:

; @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*" 

ejemplo de salida (tiene una versión de cadena que es una pequeña adición al método wmic :)):

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 

Usando Shell.Application y lotes híbrido \ jscript.Here de 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(); 

utilizado en contra de 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

wmic funciona bien. Lo he probado en win server 2012 y Windows 8. – max

+0

Si alguien todavía está leyendo este hilo, estoy tratando de usar el método WMIC en un archivo CMD, redireccionando la salida de WMIC a un archivo y luego analizando el resultado usando FOR. Sin embargo, esto falla por completo porque el archivo de salida es UC B-2 LE (según Notepad ++). Si lo convierto en ASCII manualmente, funciona bien. También traté de analizar la salida del comando directamente sin usar un archivo, pero eso también falla, presumiblemente por la misma razón. Alguien tiene alguna idea? – Dave

+0

@Dave - [verifique esto] (http://www.dostips.com/forum/viewtopic.php?t=4266) Mañana actualizaré la respuesta. – npocmaka

0

he encontrado este código de 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 

Parece interesante ya que utiliza STRINGS de SysInternals.

0

Aquí está mi intento usando WMIC para obtener la versión del archivo de todos *.exe y *.dll dentro del directorio de Skype como ejemplo:

@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 
::******************************************************************* 
Cuestiones relacionadas