批处理:当所述版本使用点和不同数量的数字时,通过 GEQ 比较版本号

Batch: Comparing version numbers via GEQ when said version uses dots and varying number of digits

我一直在使用以下 CMD 代码来检查 Edge 版本,但是从 99 到 100 的转变似乎对代码造成了影响。

FOR /F "Tokens=2*" %%G IN ('REG QUERY "HKLM\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}" /V "pv" ^| FINDSTR "REG_SZ"') DO (IF %%H GEQ 100.0.1185.29 (ECHO Microsoft Edge is version %%H and does not require an update. & GOTO SomethingElse) ELSE (ECHO Microsoft Edge is version %%H and requires an update. & GOTO MSEdgeInstall))

现在认为,例如99.9.1150.30高于100.0.1185.29。现在,如果我要删除这些点,它会意识到 999115030 实际上小于 1000118529。有一些关于点和额外数字的存在导致 cmd 中的计算失败。

有什么聪明的方法可以解决这个问题,还是我必须在从现在开始进行比较之前从注册表查询中删除这些点?

取决于你想要version-matching走多远。

如果只想匹配主版本,那么

FOR /F "Tokens=3*delims=. " %%H IN ('REG QUERY "HKLM\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}" /V "pv" ^| FINDSTR "REG_SZ"') DO (IF %%H GEQ 100 (ECHO Microsoft Edge is version %%H.%%I and does not require an update. & GOTO SomethingElse) ELSE (ECHO Microsoft Edge is version %%H.%%I and requires an update. & GOTO MSEdgeInstall))

不然就更复杂了。您的代码将检测到的版本与所需版本匹配为 string,因为这两个字符串不是纯数字的。即使删除点,您也需要单独比较每个组件,因为版本 100.1 会小于 99.10 (1001 < 9910).

请注意,我已将元变量从 %%G 更改为 %%H

我建议

FOR /F "Tokens=3" %%H IN ('REG QUERY "HKLM\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}" /V "pv" ^| FINDSTR "REG_SZ"') DO (call :vercmp %%H 100.0.1185.29 & if defined vergt (ECHO Microsoft Edge is version %%H and does not require an update. & GOTO SomethingElse) ELSE (ECHO Microsoft Edge is version %%H and requires an update. & GOTO MSEdgeInstall))

和子例程:vercmp

:vercmp
set "vergt="
for /f "delims=." %%V in ("%1") for /f "delims=." %%v in ("%2") do (
 if %%V lss %%v (goto :eof) else if %%V neq %%v (set "vergt=Y"&goto :eof)
 if %%W lss %%w (goto :eof) else if %%W neq %%w (set "vergt=Y"&goto :eof)
 if %%X lss %%x (goto :eof) else if %%X neq %%x (set "vergt=Y"&goto :eof)
 if %%Y geq %%y set "vergt=Y"
)
goto :eof

如果 %1>%2 以所需方式设置,则应将 vergt 设置为 Y


这是我使用的一些一般准则

@ECHO OFF
:: The above line should be used to start all batch programs. It's easy to change "OFF" to "ON" for debugging
:: It turns command-echoing off. A line starting "@" will never be echoed.

:: Next, one of these two - not both

SETLOCAL
SETLOCAL ENABLEDELAYEDEXPANSION

:: SETLOCAL establishes a local environment which lasts until end-of-file or an ENDLOCAL statement is reached
:: The local environment is a copy of the current environment, but any changes made to the environment
:: will be undone and the original environment restored when the end-of-file or an ENDLOCAL statement is reached
:: qv for enabledelayedexpansion

:: Setting variables
::
:: Variables may contain alphabetical characters or numerics or some symbols, but should not start with a numeric.
:: They are case-insensitive, as is batch generally - with one major exception (qv)
:: 
:: Syntax for setting string variables
SET "sourcedir=u:\your files"

:: The following formats are NOT recommended
SET sourcedir=u:\your files
:: because trailing spaces on the line would be included in the value assigned.
SET "sourcedir = u:\your files"
:: because the spaces would be included in both the variable name and in the value assigned.
:: This would set the variable "sourcedir " to the value " u:\your files"
SET "sourcedir="u:\your files""
SET sourcedir="u:\your files"
SET "sourcedir=u:\your files\"
:: because it turns out to be easier to concatenate variable values (which is done often in batch) if those
:: values are quoteless and do not have a terminal "\" (or space)

:: Syntax for setting numeric variables
SET /a var=6
:: where the "value assigned" may be a formula like 3 + 7*(avar + 1)

:: Numerics are integers in the range -(2**32) to (2**32)-1
:: BUT they are stored as strings, and can be used as strings. 
:: BEWARE - batch interprets a string that starts with a zero as OCTAL

:: Concatenating variables
SET "filename1=%sourcedir%\recstruct.txt"
:: put a variable name between "%" signs to access the valur of that variable.

:: Substringing variables
SET "substring=%filename1:m,n%"
:: (where m and n are integers)
:: sets the variable SUBSTRING to the n characters starting at character m
:: m is counted from 0 as the first character of the string
:: ,n is optional. If missing, returns the string except the first m characters
:: If m or n is negative, it is the number of characters from the end of the string

:: For loops
FOR %%X IN (one two three) DO ECHO %%X
:: The metavariable X must be a single LETTER and is CASE-SENSITIVE.

:: Two colons is an unreachable label and is often used for comments
REM is the documented remark statement but takes longer to type and is more visually intrusive

FOR %%X IN (one two three) DO (
 ECHO %%X...once
 REM comments within a code block must be of the REM form, not ::
 ECHO %%X...twice
 ECHO %%X...thrice
)
:: Parenthesising lines of code - typically in a "FOR" statement forms a "code block"
:: Such blocks are first evaluated, then executed so if you are varying a variable
:: within the block, you need DELAYEDEXPANSION and use !var! to access the new value
:: See Stephan's DELAYEDEXPANSION link: 
:: for details

CALL xsubroutine optionalparameters
:: Executes the commands in the executable "xsubroutine", typically "xsubroutine.bat" 

CALL :isubroutine optionalparameters
:: Executes the commands in the internal routine :isubroutine. The label :isubroutine must
:: be in this file (the ":" indicates "internal")

:: This command jumps to the end of this batch file. 
:: CMD understands ":EOF" to be end-of-file, and it should not be added as a user label.
GOTO :EOF

:: Were it not for the GOTO :EOF. batch would simply careen through here to the next instruction
                                                 
:: Here's the subroutine isubroutine
:isubroutine
ECHO IN subroutine
:: then go to end-of-file to exit the subroutine and return to the command following the CALL

GOTO :EOF

:: Here are other internal subroutines
:: Each internal subroutine should follow a "goto :eof" statement. 
:: It doesn't really matter where that "goto :eof" is in the code. 
:isubroutine2
ECHO IN subroutine2

GOTO :EOF

虽然 Magoo 的代码在某处对我来说出错了,或者我不够聪明,无法理解它,但它确实给了我一个很好的建议,让我可以单独比较每个数字,所以感谢你的 Magoo。我会投票给你,但我的排名显然太低了。

我想到的是以下内容:

@ECHO Off

SET "DesiredVersionColumn01=100"
SET "DesiredVersionColumn02=0"
SET "DesiredVersionColumn03=1185"
SET "DesiredVersionColumn04=29"

FOR /F "Tokens=3*" %%G IN ('REG QUERY "HKLM\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}" /V "pv" ^| FINDSTR "REG_SZ"') DO (SET "CurrentVersionFull=%%G")
FOR /F "Tokens=1* Delims=. " %%G IN ('ECHO %CurrentVersionFull%') DO (SET "CurrentVersionColumn01=%%G" & SET "CurrentVersionColumnRemaining=%%H")
FOR /F "Tokens=1* Delims=. " %%G IN ('ECHO %CurrentVersionColumnRemaining%') DO (SET "CurrentVersionColumn02=%%G" & SET "CurrentVersionColumnRemaining=%%H")
FOR /F "Tokens=1* Delims=. " %%G IN ('ECHO %CurrentVersionColumnRemaining%') DO (SET "CurrentVersionColumn03=%%G" & SET "CurrentVersionColumn04=%%H")

REM These are just for show, not really needed:
ECHO Edge Full Version: %CurrentVersionFull%

ECHO Edge Version Without Dots: %CurrentVersionColumn01% %CurrentVersionColumn02% %CurrentVersionColumn03% %CurrentVersionColumn04%

REM Version Checking
ECHO Ensuring that Microsoft Edge is version %DesiredVersionColumn01%.%DesiredVersionColumn02%.%DesiredVersionColumn03%.%DesiredVersionColumn04% or above.
IF %CurrentVersionColumn01% GTR %DesiredVersionColumn01% (ECHO Microsoft Edge is version %CurrentVersionFull% and does not require an update. C1 & GOTO NoInstall)
IF %CurrentVersionColumn01% EQU %DesiredVersionColumn01% IF %CurrentVersionColumn02% GTR %DesiredVersionColumn02% (ECHO Microsoft Edge is version %CurrentVersionFull% and does not require an update. C2 & GOTO NoInstall)
IF %CurrentVersionColumn02% EQU %DesiredVersionColumn02% IF %CurrentVersionColumn03% GTR %DesiredVersionColumn03% (ECHO Microsoft Edge is version %CurrentVersionFull% and does not require an update. C3 & GOTO NoInstall)
IF %CurrentVersionColumn03% EQU %DesiredVersionColumn03% IF %CurrentVersionColumn04% GEQ %DesiredVersionColumn04% (ECHO Microsoft Edge is version %CurrentVersionFull% and does not require an update. C4 & GOTO NoInstall)
ECHO ECHO Microsoft Edge is version %CurrentVersionFull% and requires an update. C Full & GOTO Install


:Install
ECHO Installing
PAUSE
EXIT

:NoInstall
ECHO Not Installing
PAUSE
EXIT

我认为现在是 error-proof。如果不是那我就错过了哈哈。

我仍然会尝试找出为什么 Magoo 的代码对我来说是错误的,因为它似乎比我的更有效率。