4

我正在使用以下内容来获取文件的文件版本:

sigcheck.exe -n "C:\some.exe"

以上返回类似:12,2,0,6837。

我怎样才能得到这个版本号。删除 , 以生成 1 个大数字,然后将其与存储在 txt 文件名称中的另一个版本号进行比较,例如:12.3.0.7218.txt(即与存储在文件中的文件版本类似的事情名称:删除 .'s 以形成一个大数字)。

如果名称中包含版本的文件晚于应用程序文件版本(即安装更新),我需要能够在批处理文件中执行一些代码。

4

4 回答 4

14

您不能简单地删除逗号(节点分隔符)并比较单个数字 - 它可能不会给出正确的结果。

例如,12.3 和 1.23 都会导致 123,从而导致错误的等价结论。您必须一次比较一个节点,从左侧开始。一旦你发现一个节点的不同之处,你就会得到答案。如果在一个版本用完节点之前节点是等价的,则节点多的版本更大:1.2.2 > 1.2

编辑
有时公司会在一个节点上添加一个字母后缀。这封信应该被认为是一个新的节点。搜索和替换可用于在每个字母之前引入节点分隔符。搜索和替换不区分大小写,因此aequals A

@echo off
setlocal
call :testVersions  2.1      1.9
call :testVersions "2,1"     1-9
call :testVersions  1.9      2.1
call :testVersions  1.13     1.4
call :testVersions  1.4      1.13
call :testVersions  1.3.4    1.3.4
call :testVersions  1.3.4    1.3.5
call :testVersions  1.3.5    1.3.4
call :testVersions  1.3.5    1.3.5.1
call :testVersions  1.3.5.1  1.3.5
call :testVersions  1.3b     1.3
call :testVersions  1.3      1.3b
call :testVersions  1.10a    1.9
call :testVersions  1.9      1.10a
call :testVersions  1.9a     1.9b
call :testVersions  1.9b     1.9a
call :testVersions  1.9a     1.9A
exit /b


:testVersions  version1  version2
call :compareVersions %1 %2
if %errorlevel% == 1 set "result=greater than"
if %errorlevel% == -1 set "result=less than"
if %errorlevel% == 0 set "result=equal to"
echo %~1 is %result% %~2
exit /b


:compareVersions  version1  version2
::
:: Compares two version numbers and returns the result in the ERRORLEVEL
::
:: Returns 1 if version1 > version2
::         0 if version1 = version2
::        -1 if version1 < version2
::
:: The nodes must be delimited by . or , or -
::
:: Nodes are normally strictly numeric, without a 0 prefix. A letter suffix
:: is treated as a separate node
::
setlocal enableDelayedExpansion
set "v1=%~1"
set "v2=%~2"
call :divideLetters v1
call :divideLetters v2
:loop
call :parseNode "%v1%" n1 v1
call :parseNode "%v2%" n2 v2
if %n1% gtr %n2% exit /b 1
if %n1% lss %n2% exit /b -1
if not defined v1 if not defined v2 exit /b 0
if not defined v1 exit /b -1
if not defined v2 exit /b 1
goto :loop


:parseNode  version  nodeVar  remainderVar
for /f "tokens=1* delims=.,-" %%A in ("%~1") do (
  set "%~2=%%A"
  set "%~3=%%B"
)
exit /b


:divideLetters  versionVar
for %%C in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do set "%~1=!%~1:%%C=.%%C!"
exit /b

- 输出 -

2.1 is greater than 1.9
2,1 is greater than 1-9
1.9 is less than 2.1
1.13 is greater than 1.4
1.4 is less than 1.13
1.3.4 is equal to 1.3.4
1.3.4 is less than 1.3.5
1.3.5 is greater than 1.3.4
1.3.5 is less than 1.3.5.1
1.3.5.1 is greater than 1.3.5
1.3b is greater than 1.3
1.3 is less than 1.3b
1.10a is greater than 1.9
1.9 is less than 1.10a
1.9a is less than 1.9b
1.9b is greater than 1.9a
1.9a is equal to 1.9A
于 2013-04-04T10:52:51.573 回答
0

将逗号转换为 [无]

set sig=12,2,0,6837
set sig=%sig:,=%
echo sig=%sig%

将文件名设置为变量,假设很多,比如名称是目录中最新的 - - 不知道细节,抱歉 - 你必须更具体。

set "file="
for /f %%i in ('dir /b /a-d /o-d *.txt') do if not defined file set file=%%~ni
set file=%file:~.=%
echo %file%

但是 - 一切都取决于您建议如何检索文件名。


所以如果你使用

:: you are manually entering NEWVER
SET newver=1230718


for /f %%i in ( ' sigcheck.exe -n "C:\some.exe" ' ) do set sig=%%i
Echo As a check, sig retrieved was %sig%

set sig=%sig:,=%
echo Which gets transformed to sig=%sig%

if %sig% lss %newver% (ECHO New version to be installed
  ) else (echo do not install new version)

现在,如果你想执行

thisbatch 1230718

你可以更换

SET newver=1230718

SET "newver=%1"

并且因为1230718是给批处理过程的第一个参数thisbatch newver将被设置为 1230718

于 2013-04-04T10:01:10.780 回答
0

删除逗号:

set "v1=12,2,0,6837"
set "v1=%v1:,=%"

删除点:

set "v2=12.3.0.7218"
set "v2=%v2:.=%"
于 2013-04-04T10:01:43.517 回答
0

如果版本号语法与标准 .NET 版本语法匹配并且 PowerShell 可用,则可以使用相当紧凑、易读的混合 .BAT/PowerShell 解决方案:

@GOTO :Tests
:CompareVersions
@powershell -command "&{exit(([version]$args[0]).CompareTo([version]$args[1]))}" "%~1" "%~2"
@IF ERRORLEVEL 1 (ECHO "%~1" is newer than "%~2")  ELSE (
 IF ERRORLEVEL 0 (ECHO "%~1" is the same as "%~2") ELSE ECHO "%~1" is older than "%~2")
@GOTO :eof

:Tests
CALL :CompareVersions  1.2      1.2.0
CALL :CompareVersions  1.2.3    1.2.3.0
CALL :CompareVersions  1.2.3.4  1.2.3.4
CALL :CompareVersions  1.2.3.4  1.2.4.3
CALL :CompareVersions  1.2.4.3  1.2.3.4
CALL :CompareVersions  1.2.3.4 01.2.3.4
CALL :CompareVersions  9.2.3.4 10.2.4.3
CALL :CompareVersions 01.2.3.4  1.2.3.4
CALL :CompareVersions 10.2.4.3  9.2.3.4
CALL :CompareVersions  1.2.3.4 1.2.03.4
CALL :CompareVersions  1.2.9.4 1.2.10.3
CALL :CompareVersions 1.2.03.4  1.2.3.4
CALL :CompareVersions 1.2.10.3  1.2.9.4

前两种情况是为了说明标准 .NET 版本的一些古怪特性 - 至少需要两个部分,如果它们为 -1,则缺失部分的行为。

我不确定 OP 帖子的更广泛背景,但知道给定 .EXE 或 .DLL,PowerShell 可以轻松地从文件中提取 IComparable 版本(例如(Get-Item $fileName).VersionInfo.FileVersionRaw)可能很有用。

于 2019-11-15T23:04:20.000 回答