批处理文件中比较版本号

4

我正在使用以下代码获取文件的版本:

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

以上返回的结果类似于:12,2,0,6837。
我该如何获取这个版本号。将逗号去掉以生成一个大数字,然后与另一个版本号进行比较,该版本号存储在txt文件的名称中,例如:12.3.0.7218.txt(即执行类似于文件版本存储在文件名中的操作:删除‘.’ 以生成一个大数字)。
如果包含版本号的文件比应用程序的文件版本更晚,我需要能够在批处理文件中执行一些代码,即安装更新。

如果去掉逗号和点,你可以比较这两个数字吗?例如:if %v1% lss %v2% ... - Endoro
考虑到一些版本号像 12.13.0.7218 :) - Endoro
4个回答

16
你不能简单地移除逗号(节点分隔符)并比较单个数字 - 这可能不会给出正确的结果。
例如,12.3和1.23都会得出123,导致错误的等价结论。您必须逐个比较节点,从左侧开始。一旦在节点中发现差异,那么您就得到了答案。如果节点相等,直到一个版本用完节点,则具有更多节点的版本较大:1.2.2 > 1.2
编辑
有时公司在节点上加上字母后缀。该字母应视为一个新节点。可以使用搜索和替换在每个字母之前引入节点分隔符。搜索和替换不区分大小写,因此a等于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

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


好的,谢谢这个。让我们把它变得更简单。如果我把第二个文件版本放在批处理文件中而不是读取它,像:1230718。所以只需要格式化第一个文件版本,然后进行比较。 - Adam Chetnik

0

去除逗号:

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

去除点号:

set "v2=12.3.0.7218"
set "v2=%v2:.=%"

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)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接