Есть ли в Windows исполняемый файл, который я могу запустить в командной оболочке, который возвращает номер версии исполняемого файла (.exe)?

Я вижу много вопросов, которые показывают, как это сделать на разных языках, и ссылки на стороннее программное обеспечение для его написания, но я не могу найти простую команду оболочки для этого. Дополнительные баллы, если мне не нужно ничего устанавливать.

Он должен запускаться как обычный пользователь. Не администратор.

27
neves 3 Сен 2014 в 19:24
 – 
josh poley
3 Сен 2014 в 19:36

7 ответов

Лучший ответ
wmic datafile where name="C:\\Windows\\System32\\msiexec.exe" get Version /value 

Вы можете использовать wmic для этого. И вы можете обернуть это в командный файл

@echo off
    setlocal enableextensions

    set "file=%~1"
    if not defined file goto :eof
    if not exist "%file%" goto :eof

    set "vers="
    FOR /F "tokens=2 delims==" %%a in ('
        wmic datafile where name^="%file:\=\\%" get Version /value 
    ') do set "vers=%%a"

    echo(%file% = %vers% 

    endlocal

Сохраните его как (пример) getVersion.cmd и назовите getVersion.cmd "c:\windows\system32\msiexec.exe"

отредактировано , чтобы адаптироваться к комментариям и не требовать прав администратора. В этом случае для запроса wmi используется гибридный файл cmd / javascript. То же использование

@if (@this==@isBatch) @then
@echo off
    setlocal enableextensions

    set "file=%~f1"
    if not exist "%file%" goto :eof

    cscript //nologo //e:jscript "%~f0" /file:"%file%"

    endlocal

    exit /b
@end
    var file = WScript.Arguments.Named.Item('file').replace(/\\/g,'\\\\');
    var wmi = GetObject('winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\cimv2')
    var files = new Enumerator(wmi.ExecQuery('Select Version from CIM_datafile where name=\''+file+'\'')) 

    while (!files.atEnd()){
        WScript.StdOut.WriteLine(files.item().Version);
        files.moveNext();
    };
    WScript.Quit(0)
34
MC ND 4 Сен 2014 в 00:56
1
Отлично, но, к сожалению, вы должны быть в группе администраторов, чтобы запустить его :-( Мне нужно запустить его как мой пользователь непрерывной интеграции.
 – 
neves
3 Сен 2014 в 23:15
Как потом использовать% vers%? Когда я пытаюсь echo %vers%, командная строка сообщает мне ECHO is off.
 – 
AlainD
16 Май 2018 в 20:09
@AlainD, setlocal / endlocal предотвращает распространение изменений в среде за пределы командного файла. Если вам нужно значение %vers%, измените конечную строку endlocal на enlocal & set "vers=%vers%"
 – 
MC ND
16 Май 2018 в 22:13
@ mc-nd небольшая опечатка: enDlocal & set "vers =% vers%
 – 
Andrew Dennison
12 Ноя 2019 в 18:33
2
@AndrewDennison, вы правы, спасибо. К сожалению, мне не разрешено редактировать комментарий.
 – 
MC ND
13 Ноя 2019 в 00:24

Если вы хотите и можете использовать PowerShell, следующий код будет работать. Если вы используете поддерживаемую систему Windows, PowerShell будет доступен.

(Get-Item -Path 'C:\Program Files\Java\jdk1.8.0_144\bin\java.exe').VersionInfo |
    Format-List -Force

Если вам необходимо запустить его в оболочке cmd.exe, вы можете использовать:

powershell -NoLogo -NoProfile -Command ^
    "(Get-Item -Path 'C:\Program Files (x86)\Java\jre1.8.0_201\bin\java.exe').VersionInfo |" ^
        "Format-List -Force"
21
lit 20 Мар 2020 в 22:49
2
Это самый простой и ясный ответ, который напрямую применим к PS без каких-либо других зависимостей.
 – 
not2qubit
26 Апр 2020 в 09:36
Но ProductVersion и FileVersion могут быть пустыми в PowerShell 7.2.5.
 – 
user894319twitter
5 Июл 2022 в 07:13
@user894319twitter, у pwsh.exe есть значения; FileVersion : 7.2.5.500, ProductVersion : 7.2.5 SHA: 0aad398b0e918ce7d73dca929ca6395639085b21. Ни один инструмент не может контролировать, вводит ли создатель файла информацию в поле. Я не понимаю вашу точку зрения.
 – 
lit
5 Июл 2022 в 17:15
set EXE='c:\firefox\firefox.exe'
powershell "(Get-Item -path %EXE%).VersionInfo.ProductVersion"
15
bviktor 30 Янв 2018 в 12:36
Хотя этот ответ, состоящий только из кода, может дать ответ на вопрос, пожалуйста, объясните, почему он это делает. Это поможет будущим пользователям оценить ответ для своей ситуации.
 – 
Tom Brunberg
30 Янв 2018 в 15:45
4
"добавить объяснение, почему это так" Потому что это сделано? Эти вопросы о шаблоне бессмысленны.
 – 
bviktor
30 Янв 2018 в 20:20
Нет, потому что вы установили текущий активный exe-файл, Powershell будет интерпретировать его с первой строкой, а затем вы использовали команду powershell для текущего активного exe-файла.
 – 
Overmind
24 Май 2018 в 14:41
1
Какие? Я активно использую этот фрагмент в нескольких работах Дженкинса, но, пожалуйста, скажите мне, почему он не работает, или что-то еще ...
 – 
bviktor
24 Май 2018 в 18:44
Но ProductVersion и FileVersion могут быть пустыми в PowerShell 7.2.5.
 – 
user894319twitter
5 Июл 2022 в 07:05

И в одну сторону с makecab:

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

Пример вывода (у него строковая версия, которая является небольшим дополнением к методу 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

Также вы можете взглянуть на tooltipinfo.bat

3
npocmaka 30 Янв 2018 в 13:40

Filever c: \ windows \ system32 \ notepad.exe (файловая программа предустановлена ​​в каждой ОС Windows).

2
Sergei Meleshchuk 7 Ноя 2020 в 05:24
1
Я набрал where filever и ничего не нашел.
 – 
neves
9 Ноя 2020 в 16:24
4
Судя по всему, filever больше не доступен в Windows 10. Хотя OP не указывал версию ОС, я добавляю этот комментарий для будущих читателей.
 – 
Ro Yo Mi
7 Дек 2020 в 21:26

Filever.exe находится в SUPPORT.CAB инструментов поддержки Windows 2003 и, возможно, в других местах.

Метод, использующий VBScript и Scripting.FileSystemObject из сценария CMD

@Echo off
Set Version=
Echo WScript.Echo "Set Version=" ^& CreateObject("Scripting.FileSystemObject").GetFileVersion("%SystemRoot%\notepad.exe") >%temp%\~FileVer.vbs
Cscript.exe //nologo %temp%\~FileVer.vbs>%temp%\~FileVer.cmd
Call %temp%\~FileVer.cmd
Echo Version=%Version%

Вариант метода powershell, если вы вызываете из сценария CMD. Использование FileVersionRaw вместо FileVersion, потому что FileVersion может иметь дополнительное текстовое оформление, но для получения ожидаемого формата требуется ToString ().

@Echo off
Set Version=
Powershell -c "'Set Version=' + (Get-Command '%SystemRoot%\Notepad.exe').FileVersionInfo.FileVersionRaw.ToString()">%temp%\~FileVer.cmd
Call %temp%\~FileVer.cmd
Echo Version=%Version%

Метод Powershell из CMD для сравнения версий, поскольку это может быть причиной запроса в первую очередь. Необходимо использовать% ErrorLevel% == x, потому что ErrorLevel == x на самом деле больше или равно.

@echo off
Powershell -c "exit 10 + ((Get-Command '%SystemRoot%\Notepad.exe').FileVersionInfo.FileVersionRaw).CompareTo([System.Version] '10.0.19041.1')"
If %ErrorLevel%==9  Echo File needs updating
If %ErrorLevel%==10 Echo File is expected version
If %ErrorLevel%==11 Echo File is newer than expected
0
JellyHead 1 Дек 2020 в 03:17

Это даст вам только версию файла:

wmic datafile where name='c:\\windows\\system32\\notepad.exe' get version

Результат:

Version
6.1.7601.18917
12
MrCalvin 24 Сен 2017 в 09:58
Привет, ответы, содержащие только код, обычно помечаются для модерации. Не могли бы вы добавить строку, объясняющую, что это нравится?
 – 
stef
23 Сен 2017 в 21:05
1
Этот ответ должен быть на высоте. Коротко, лаконично и по делу, не говоря уже о работе, в отличие от принятого в настоящее время ответа!
 – 
Björn Larsson
30 Апр 2021 в 13:40