在从Windows运行的批处理文件中,使用目录名称选择最新的应用程序版本

时间:2016-12-07 18:05:12

标签: batch-file

我使用经常更新的便携式应用程序。问题是应用程序的每个版本都有一个名为“processing-x.y.z”的文件夹。每次安装新版本时,我都需要将文件与位于不同文件夹中的新版本相关联。因此,为了解决这个烦恼,我想将“* .pde”文件类型与批处理文件相关联。

文件夹名称如下

  • 处理-3.2.1
  • 处理-3.2.2

我创建了这个小批量脚本,从最新版本获取可执行文件。

@echo off

for /f "delims=" %%D in ('dir processing* /a:d /b /o-n') do (
  set currentFolder=%%~fD

  :: Check if environment variable already set
  if not %currentFolder%==%processing% (
    :: Set environment variable processing
    setx processing %currentFolder%
  )

  %currentFolder%/processing.exe %1
  goto :eof
)

从命令行启动时有效,但在Windows中无法启动。有具体原因吗?另外,有没有办法优化此代码?

由于

3 个答案:

答案 0 :(得分:1)

假设版本号始终由一个数字组成,我会按以下方式进行:

@echo off

rem // Reset variable:
set "currentFolder="
rem /* Loop through the folders in ascending order, overwrite the variable
rem    in each iteration, so it holds the highest version finally: */
for /f "delims=" %%D in ('dir /B /A:D /O:N "processing-*.*.*"') do (
    set "currentFolder=%%~fD"
)

rem // Check if environment variable is already set:
if not "%processing%"=="%currentFolder%" (
    rem // Set environment variable `processing`:
    setx processing "%currentFolder%"
)

rem // Execute `processing.exe`:
"%currentFolder%/processing.exe" "%~1"

如果单个版本号可以包含多个数字(此处最多四个),请使用:

@echo off
setlocal EnableExtensions EnableDelayedExpansion
rem /* Assign each found folder to a variable called `$ARRAY_X_Y_Z`, where `X`, `Y`, `Z`
rem    are zero-padded variants of the original numbers `x`, `y`, `z`, so for instance,
rem    a folder called `processing-4.7.12` is stored in variable `$ARRAY_0004_0007_0012`: */
for /F "tokens=1-4 delims=-. eol=." %%A in ('
    dir /B /A:D "processing-*.*.*" ^| ^
    findstr /R /I "^processing-[0-9][0-9]*.[0-9][0-9]*.[0-9][0-9]*$"
') do (
    rem // Perform the left-side zero-padding here:
    set "MAJ=0000%%B" & set "MIN=0000%%C" & set "REV=0000%%D"
    set "$ARRAY_!MAJ:~-4!_!MIN:~-4!_!REV:~-4!=%%A-%%B.%%C.%%D"
)
rem // Reset variable:
set "currentFolder="
rem /* Loop through the output of `set "$ARRAY_"`, which returns all variables beginning
rem    with `$ARRAY_` in ascending alphabetic order; because of the zero-padding, where
rem    alphabetic and alpha-numeric orders become equivalent, the item with the greatest
rem    version number item is iterated lastly, therefore the latest version is returned: */
for /F "tokens=1,* delims==" %%E in ('set "$ARRAY_"') do (
    set "currentFolder=%%F"
)
endlocal & set "currentFolder=%currentFolder%"

rem // The rest of the script os the same as above...

您也可以在这里找到类似的方法:

答案 1 :(得分:0)

未经测试(编辑:应处理次要版本有更多数字的情况):

@echo off
setlocal enableDelayedExpansion

    set /a latest_n1=0
    set /a latest_n2=0
    set /a latest_n3=0

for /f "tokens=2,3* delims=-." %%a in ('dir processing* /a:d /b /o-n') do (
    set "current_v=%%a.%%b.%%c"
    set /a "current_n1=%%a"
    set /a "current_n2=%%b"
    set /a "current_n3=%%c"

    if !current_n1! GTR !latest_n1! (

        set /a latest_n1=!current_n1!
        set /a latest_n2=!current_n2!
        set /a latest_n3=!current_n3!

        set "latest_v=!current_v!"
    ) else  if !current_n1! EQU !latest_n1! if !current_n2! GTR !latest_n2! (

        set /a latest_n1=!current_n1!
        set /a latest_n2=!current_n2!
        set /a latest_n3=!current_n3!

        set "latest_v=!current_v!"
    ) else if !current_n1! EQU !latest_n1! if !current_n2! EQU !latest_n2! if !current_n3! GTR !latest_n3! (

        set /a latest_n1=!current_n1!
        set /a latest_n2=!current_n2!
        set /a latest_n3=!current_n3!

        set "latest_v=!current_v!"
    )

)

echo latest version=processing-%latest_v%

答案 2 :(得分:0)

@echo off

for /f "delims=" %%D in ('dir processing* /a:d /b /o-n') do (
 if "%processing%" neq "%cd%\%%F" setx processing "%cd%\%%F" >nul
 .\%%F\processing.exe %1
 goto :eof
)

是等效的代码 - 差不多。

第一个问题 - ::形式的注释不应该在代码块(带括号的系列语句)中使用,因为::实际上是一个标签,它本身用冒号加星标。由于它是一个标签,它会终止该块。

下一个问题 - 在代码块中遇到%var% refers to the value of var **as it stood when the for ** - 而不是在循环内发生变化。

下一个问题 - 正如其他人所指出的那样,/o-n会产生一个名字序列,因此10可能会在 9之后对进行排序(因为排序)相反)。我在替换代码中没有更改此内容,但按{-1}}按反向日期排序可能更适合您的应用。

现在您的代码如何运作。

首先,/o-d设置为上次运行建立的任何内容。如果 与此次运行计算的值不同,则processing为新值。奇怪的是,setx不会setx当前set实例中的值,仅适用于将来创建的实例。

然后,您尝试执行您的流程,然后使用cmd退出批处理。唯一的问题是goto :eof 由循环更改的值,因为它应该在代码块中。由于%currentfolder%已经破坏了块,并且代码中使用了::-comments,因此出现 。< / p>

相反,使用currentfolder表示当前目录名(.\%%F\executablename)&#34 ;;子目录.; filenametoexecute&#34; - 请注意&#34; \&#34;是Windows中的目录分隔符,&#39; /&#39;表示开关。