无忧启动论坛

标题: 帮我看看我的批处理怎么出错,我找不到错误…… [打印本页]

作者: gogo11    时间: 2016-4-14 13:30
标题: 帮我看看我的批处理怎么出错,我找不到错误……
帮我看看我的批处理怎么出错,怎么找都没错误啊!


@echo off
cd /d "%~dp0"&color 07 &title 解压外置更新文件文件,请稍候……
ver | find "5.1" > NUL && set WIN=winxp && goto Subroutine
ver | find "6.1" > NUL && set WIN=win7 && goto Subroutine
ver | find "6.2" > NUL && set WIN=win8  && goto Subroutine
ver | find "6.3" > NUL && set WIN=win8.1  && goto Subroutine
ver | find "10" > NUL && set WIN=win10 && goto Subroutine
:: ================================
:winxp.x86
pause
echo %WIN%
pause
echo 0
:win7.x86
echo  %WIN%.x86  && exit 0
:win7.x64
echo  %WIN%.x64  && exit 0
:win8.x86
echo  %WIN%.x86  && exit 0
:win8.x64
echo  %WIN%.x64  && exit 0
:win10.32
echo  %WIN%.x86  && exit 0
:win10.x64
echo  %WIN%.x64  && exit 0
:Subroutine
if "%PROCESSOR_ARCHITECTURE%"=="x86"   set WIN=%WIN%.x86 && echo %WIN%  && pause && goto %WIN%  || echo x86 error && pause
if "%PROCESSOR_ARCHITECTURE%"=="AMD64"  set WIN=%WIN%.x64 && echo %WIN%  && pause && goto %WIN%  || echo x64 error && pause




作者: captain_g    时间: 2016-4-14 16:47
看看出错提示,显然批处理中有命令没有成功执行,以32位WIN7系统为例,为进行排查:
将这一句:ver | find "6.1" > NUL && set WIN=win7 && goto Subroutine
改为这样:ver | find "6.1" > NUL && set WIN=win7&& goto Subroutine
将这一段:
:win7.x86
echo  %WIN%.x86  && exit 0
改成这样:
:win7.x86
echo %WIN% && echo 没问题!
pause
再将这段:if "%PROCESSOR_ARCHITECTURE%"=="x86" set WIN=%WIN%.x86 && echo %WIN%  && pause && goto %WIN%  || echo x86 error && pause
改成这样:
if "%PROCESSOR_ARCHITECTURE%"=="x86" set WIN=%WIN%.x86
goto %WIN%  || echo x86 error && pause

作者: captain_g    时间: 2016-4-14 17:01
第一处改动:为避免win7与.x86之间出现空格;
第二处改动:为避免出现win7.x86.x86及排查的结果;
第三处改动:||之前有错,无法设定WIN为win7.x86;
作者: gogo11    时间: 2016-4-15 13:23
我测试一下,谢谢~
作者: gogo11    时间: 2016-4-15 13:31
好像set WIN=%WIN%.x86这句没有执行成功~~~~~~~~·
作者: gogo11    时间: 2016-4-15 13:35
这个是个精简的,还是出错,M赋值好像出错!就是找不到出错原因

作者: gogo11    时间: 2016-4-15 13:42
本帖最后由 gogo11 于 2016-4-15 13:48 编辑

if里边好像只能有一个语句,不能&& ,两个就出错!!!!!!!!不过上边那个带pause的就正确,没出问题~也不见高手来帮我解决一下……



作者: 527104427    时间: 2016-4-15 15:52
gogo11 发表于 2016-4-15 13:42
if里边好像只能有一个语句,不能&& ,两个就出错!!!!!!!!不过上边那个带pause的就正确,没出问题~ ...

变量延迟嘛。。。

这句
if "%PROCESSOR_ARCHITECTURE%"=="x86"   set WIN=%WIN%.x86 && echo %WIN%  && pause && goto %WIN%  || echo x86 error && pause
改成:
if "%PROCESSOR_ARCHITECTURE%"=="x86"   set WIN=%WIN%.x86 && call echo %WIN%  && pause && goto %WIN%.x86 || echo x86 error && pause


非得纠结 && 后不能goto %WIN% 的问题,那也可以用下面的:

if "%PROCESSOR_ARCHITECTURE%"=="x86"   set WIN=%WIN%.x86 && call echo %WIN%  && pause && call :goto || echo x86 error && pause
goto :eof
:goto
goto %WIN%
goto :eof

作者: colorskywei    时间: 2016-5-28 17:33
@echo off
rem 启用延迟变量
SETLOCAL ENABLEDELAYEDEXPANSION

@echo off
cd /d "%~dp0"&color 07 &title 解压外置更新文件文件,请稍候……
ver | find "5.1" > NUL && set WIN=winxp && goto Subroutine
ver | find "6.1" > NUL && set WIN=win7 && goto Subroutine
ver | find "6.2" > NUL && set WIN=win8  && goto Subroutine
ver | find "6.3" > NUL && set WIN=win8.1  && goto Subroutine
ver | find "10" > NUL && set WIN=win10 && goto Subroutine
:: ================================
:winxp.x86
pause
echo %WIN%
pause
echo 0
:win7.x86
echo  %WIN%  && echo 没问题!&& pause && exit
:win7.x64
echo  %WIN%  && echo 没问题!&& pause && exit
:win8.x86
echo  %WIN%  && echo 没问题!&& pause && exit
:win8.x64
echo  %WIN%  && echo 没问题!&& pause && exit
:win10.32
echo  %WIN%  && echo 没问题!&& pause && exit
:win10.x64
echo  %WIN%  && echo 没问题!&& pause && exit
:Subroutine
if "%PROCESSOR_ARCHITECTURE%"=="x86"   set WIN=!WIN: =!.x86 && echo !WIN!  && pause && goto !WIN!  || echo x86 error && pause
if "%PROCESSOR_ARCHITECTURE%"=="AMD64"  set WIN=!WIN: =!.x64 && echo !WIN!  && pause && goto !WIN!  || echo x64 error && pause

作者: nttwqz    时间: 2016-5-28 19:25
不知道楼主是用来干嘛的,下面的仅供参考!


  1. @echo off
  2. set build=更新日期:2016-5-8
  3. title 自动安装    %build%
  4. setlocal enabledelayedexpansion

  5. rem 检测当前系统版本名称
  6. for /f "delims=W tokens=2*" %%a in ('net config workstation^|findstr /i Windows') do set "sysver=W%%a"

  7. rem 检测当前系统的版本
  8. for /f "tokens=2 delims=[" %%P in ('ver') do (
  9.         for /f "tokens=2" %%Q in ("%%P") do set ver=%%Q
  10.         for /f "tokens=1-2 delims=." %%R in ("!ver!") do set ver=%%R.%%S
  11. )


  12. rem 自动请求以管理员权限运行
  13. echo CreateObject^("Shell.Application"^).ShellExecute "%~f0", "", "", "runas", 1 > "%temp%\getadmin.vbs"
  14. reg query HKU\S-1-5-20>nul 2>nul||cscript //b "%temp%\getadmin.vbs"&&del "%temp%\getadmin.vbs" /f /q>nul 2>nul&&exit /b


  15. rem 根据不同系统设置不同的背景色
  16. if !ver!==5.1 color 1f
  17. if !ver!==6.1 color 3f
  18. if !ver! GEQ 6.2 color 5f

  19. rem 系统类型判断
  20. if exist %WINDIR%\SysWOW64 set osarch=x64
  21. if not exist %WINDIR%\SysWOW64 set osarch=x86

  22. rem 显示当前系统
  23. if !ver! GEQ 6.1 echo 您的系统是%sysver% %osarch%
  24. if !ver!==5.1 echo 您的系统是Windows XP %osarch%
复制代码

作者: dos时代菜鸟    时间: 2016-5-28 22:47
本帖最后由 dos时代菜鸟 于 2016-5-28 23:36 编辑

何必那么麻烦?


  1. @echo off
  2. SETLOCAL ENABLEDELAYEDEXPANSION
  3. set verx=Null
  4. for /f "tokens=4" %%c in ('ver')  do (
  5.         for /f "delims=. tokens=1,2,3*" %%f in ("%%c") do (
  6.                 if %%f.%%g equ 5.1 set "verx=WINXP"
  7.                 if %%f.%%g equ 6.1 set "verx=WIN7"  
  8.                 if %%f.%%g equ 6.2 set "verx=WIN8"
  9.                 if %%f.%%g equ 6.3 set "verx=WIN8.1"
  10.                 if %%f     equ 10  set "verx=WIN10"
  11.         )
  12. )
  13. set "verx=!verx!.%PROCESSOR_ARCHITECTURE%"
  14. if /i "%PROCESSOR_ARCHITECTURE%"=="AMD64" set verx=!verx:AMD64=X64!
  15. ECHO !verx!

  16. pause
复制代码

作者: dos时代菜鸟    时间: 2016-5-28 23:43
nttwqz 发表于 2016-5-28 19:25
不知道楼主是用来干嘛的,下面的仅供参考!


不能用 那个方法 判断 系统 名称 ,涉及到WES系统
作者: nttwqz    时间: 2016-5-29 00:44
dos时代菜鸟 发表于 2016-5-28 22:47
何必那么麻烦?

话说,我当时测试了XP~Win10所有系统,也有特意将cmd改为其它语言,也不知道是发现了什么问题,才用了[来分隔,需要for中嵌套两个for才获得版本号,而不像你直接一步就分理出了数字部分,两步就得到了版本号,这一点比我高明。

第四行 set verx=Null什么意思,用来显示未知版本?


记得以前哪位高人说过,delims可以用多个分隔符,你知不知道怎么用,一直试不出来,要是能的话,一步就得到结果了。
作者: nttwqz    时间: 2016-5-29 00:47
dos时代菜鸟 发表于 2016-5-28 23:43
不能用 那个方法 判断 系统 名称 ,涉及到WES系统

哪有什么更好的方法显示具体版本名称,比如Windows 8.1 China 等等,虽然我涉及不到WES

我要下面的结果

您的系统是Windows 8.1 Enterprise x64,而非Win8.1.x64
作者: nttwqz    时间: 2016-5-29 08:52
本帖最后由 nttwqz 于 2016-5-29 08:53 编辑
dos时代菜鸟 发表于 2016-5-28 22:47
何必那么麻烦?


原因了找到了,因为WinXP输入ver得到的结果是这样的

Microsoft Windows XP [版本 5.1.2600]

用空格分隔的第四部分变成了“[版本”,无法正确获得版本号,所以我才那么麻烦,如果tokens能像set命令一样取倒数第一部分就好了。


看来你一定没有实机测试,我这批处理可是用过很多次的,确定可靠
作者: dos时代菜鸟    时间: 2016-5-29 15:08
本帖最后由 dos时代菜鸟 于 2016-5-29 15:16 编辑

如果确定是 简体中文
可以如图:


或者 直接把 代码改成 如下 用 [  和 默认分割符 进行 两次分割 处理 得到 具体版本号  :

  1. @echo off
  2. SETLOCAL ENABLEDELAYEDEXPANSION
  3. set verx=Null
  4. for /f "tokens=2 delims=[" %%c in ('ver')  do (
  5. for /f "tokens=2" %%i in ("%%c") do (
  6.         for /f "delims=. tokens=1,2,3*" %%f in ("%%i") do (
  7.                 if %%f.%%g equ 5.1 set "verx=WINXP"
  8.                 if %%f.%%g equ 6.1 set "verx=WIN7"  
  9.                 if %%f.%%g equ 6.2 set "verx=WIN8"
  10.                 if %%f.%%g equ 6.3 set "verx=WIN8.1"
  11.                 if %%f     equ 10  set "verx=WIN10"
  12.         )
  13. )
  14. )
  15. set "verx=!verx!.%PROCESSOR_ARCHITECTURE%"
  16. if /i "%PROCESSOR_ARCHITECTURE%"=="AMD64" set verx=!verx:AMD64=X64!
  17. ECHO !verx!

  18. pause
复制代码

作者: dos时代菜鸟    时间: 2016-5-29 15:24
本帖最后由 dos时代菜鸟 于 2016-5-29 15:48 编辑

说到逆向 取 字串内容。
set 命令 可以 逆向 取 变量 内容 ,所以 可以 将 整个 ver 命令 输出 结果 赋值 给一个变量 再 逆向 取 其 内容 直到 遇到 最 右侧 第一个 空格 。
然后 再 把这个 逆向 取出 的 变量内容 再次 逆 回来 。
呵呵。
看 下面代码 :

  1. @echo off
  2. SETLOCAL ENABLEDELAYEDEXPANSION
  3. set verx=Null
  4. for /f "delims=" %%c in ('ver')  do (
  5.         set "veri=%%c"
  6.         set "veri=!veri:[=!"
  7.         set "veri=!veri:]=!"
  8. )
  9. set "verx=" && set n=0
  10. :loop
  11.         set /a n-=1
  12.         for /f %%i in ("!n!") do (
  13.                 if "!veri:~%%i,1!"==" " goto end_loop
  14.                 set verx=!veri:~%%i,1!!verx!
  15.         )
  16.         goto loop
  17. :end_loop

  18. echo !verx!
  19. pause
复制代码


作者: 2010tljabc    时间: 2016-5-29 15:37
nttwqz 发表于 2016-5-29 08:52
原因了找到了,因为WinXP输入ver得到的结果是这样的

Microsoft Windows XP [版本 5.1.2600]

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set verx=Null
for /f "tokens=5" %%c in ('ver')  do (
  echo %%c
  for /f "delims=. tokens=1,2,3*" %%f in ("%%c") do (
    echo %%f  %%g
    if %%f.%%g equ 5.1 set "verx=WINXP"
    if %%f.%%g equ 6.1 set "verx=WIN7"  
    if %%f.%%g equ 6.2 set "verx=WIN8"
    if %%f.%%g equ 6.3 set "verx=WIN8.1"
    if %%f     equ 10  set "verx=WIN10"
  )
)
set "verx=!verx!.%PROCESSOR_ARCHITECTURE%"
if /i "%PROCESSOR_ARCHITECTURE%"=="AMD64" set verx=!verx:AMD64=X64!
ECHO !verx!

作者: dos时代菜鸟    时间: 2016-5-29 15:51
本帖最后由 dos时代菜鸟 于 2016-5-29 16:23 编辑
2010tljabc 发表于 2016-5-29 15:37
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set verx=Null


如果用 tokens=5 那么 win7 那样只有 四个字段 的 情况 又 不行了 。


如果 能够确定  ver 命令 输出 的文本流 中 最后一个单词 一定是 " 版本号]"  就可以 用 下面的代码精确锁定之(逆向提取)
  1. @echo off
  2. SETLOCAL ENABLEDELAYEDEXPANSION
  3. for /f "delims=" %%c in ('ver')  do (
  4.         set "veri=%%c"
  5.         set "veri=!veri:[=!"
  6.         set "veri=!veri:]=!"
  7. )
  8. set "verx=" && set n=0
  9. :loop
  10.         set /a n-=1
  11.         for /f %%i in ("!n!") do (
  12.                 if "!veri:~%%i,1!"==" " goto end_loop
  13.                 set verx=!veri:~%%i,1!!verx!
  14.         )
  15.         goto loop
  16. :end_loop

  17. for /f "delims=. tokens=1,2,3*" %%f in ("!verx!") do (
  18.         if %%f.%%g equ 5.1 set "verx=WINXP"
  19.         if %%f.%%g equ 6.1 set "verx=WIN7"  
  20.         if %%f.%%g equ 6.2 set "verx=WIN8"
  21.         if %%f.%%g equ 6.3 set "verx=WIN8.1"
  22.         if %%f     equ 10  set "verx=WIN10"
  23. )

  24. set "verx=!verx!.%PROCESSOR_ARCHITECTURE%"
  25. if /i "%PROCESSOR_ARCHITECTURE%"=="AMD64" set verx=!verx:AMD64=X64!

  26. ECHO !verx!

  27. pause
复制代码



如果想简单一点儿,只应对xp这样有 5个字段的,而且其他的都是 4个字段,可以这样修改原设计,只需加一个判断
  1. @echo off
  2. SETLOCAL ENABLEDELAYEDEXPANSION
  3. set verx=Null
  4. for /f "tokens=4*" %%c in ('ver')  do (
  5.         set very=%%c
  6.         if not "%%d"=="" set very=%%d
  7.         for /f "delims=. tokens=1,2,3*" %%f in ("!very!") do (
  8.                 if %%f.%%g equ 5.1 set "verx=WINXP"
  9.                 if %%f.%%g equ 6.1 set "verx=WIN7"  
  10.                 if %%f.%%g equ 6.2 set "verx=WIN8"
  11.                 if %%f.%%g equ 6.3 set "verx=WIN8.1"
  12.                 if %%f     equ 10  set "verx=WIN10"
  13.         )
  14. )
  15. set "verx=!verx!.%PROCESSOR_ARCHITECTURE%"
  16. if /i "%PROCESSOR_ARCHITECTURE%"=="AMD64" set verx=!verx:AMD64=X64!
  17. ECHO !verx!

  18. pause
复制代码



另外 还有一个命令 systeminfo 可以显示更详细的系统信息。
如果用 vbs 可能 更容易一些 ,后者用 wmic .
作者: nttwqz    时间: 2016-5-29 17:02
dos时代菜鸟 发表于 2016-5-29 15:08
如果确定是 简体中文
可以如图:


用“版本”两个字作为分隔符的话,要考虑到其它语言的系统,虽然几乎见不到,但是明显“[”来的更可靠,因为一般的需要都能显示[。

你这是分隔了三次,非两次,也嵌套两个for,和我的基本相同。以WinXP为例,第一次以“[”为分隔符得到了“版本 5.1.2600]”;第二次用默认分隔符,得到了“5.1.2600]”;第三次以“.”为分隔符,得到了最终版本号“5.1”。
作者: dos时代菜鸟    时间: 2016-5-29 22:02
本帖最后由 dos时代菜鸟 于 2016-5-29 23:12 编辑
nttwqz 发表于 2016-5-29 17:02
用“版本”两个字作为分隔符的话,要考虑到其它语言的系统,虽然几乎见不到,但是明显“[”来的更可靠, ...


可以考虑 用 逆向 确定 最后一个单词的方法 明确版本号。
也可以用 下面的 vbs 代码,将下面代码保存为一个 vbs ,在 cmd下调用之,就可以了。
  1. Set FSO=CreateObject("Scripting.FileSystemObject")

  2. v=Split(FSO.GetFileVersion(fso.GetSpecialFolder(0)&"\explorer.exe"),".",3)
  3. VX="Unknow"
  4. Select Case CCur(v(0)&"."&v(1))
  5.                 Case 5.1 vx="WINXP"
  6.                 Case 6.1 vx="WIN7"
  7.                 Case 6.2 vx="WIN8"
  8.                 Case 6.3 vx="WIN8.1"
  9. End Select
  10. If v(0)="10"  Then  vx="WIN10"

  11. st="X86"
  12. If fso.folderExists(fso.GetSpecialFolder(0)&"\SysWOW64") Then st="X64"

  13. wscript.echo VX&"."&st
复制代码


下面这个 vbs 更直接:
  1. Set wmi=GetObject("winmgmts:\\.")
  2. Set operation=wmi.instancesof("win32_Operatingsystem")
  3. For Each sys In operation
  4.         WScript.Echo "系统名称:"&sys.caption
  5.         Wscript.Echo "系统版本:"&sys.Version
  6.         WScript.Echo "系统类型:"&sys.OSArchitecture
  7. Next
复制代码


下面这个 是 cmd 版的
  1. @echo off
  2. SETLOCAL ENABLEDELAYEDEXPANSION
  3. for /f "delims=, skip=2 tokens=2" %%c in ('wmic os get Version^,WindowsDirectory /format:csv') do (
  4.         for /f "delims=. tokens=1,2,3*" %%f in ("%%c") do (
  5.                 if %%f.%%g equ 5.1 set "verx=WINXP"
  6.                 if %%f.%%g equ 6.1 set "verx=WIN7"  
  7.                 if %%f.%%g equ 6.2 set "verx=WIN8"
  8.                 if %%f.%%g equ 6.3 set "verx=WIN8.1"
  9.                 if %%f     equ 10  set "verx=WIN10"
  10.         )
  11. )
  12. for /f "delims=, skip=2 tokens=2" %%c in ('wmic os get OSArchitecture^,WindowsDirectory /format:csv') do (
  13.         set verx=!verx!.%%c
  14. )
  15. echo !verx!
  16. pause
复制代码

作者: dos时代菜鸟    时间: 2016-5-30 06:36
本帖最后由 dos时代菜鸟 于 2016-5-30 06:51 编辑

根据 21 楼 代码 简化的:

  1. @echo off
  2. SETLOCAL ENABLEDELAYEDEXPANSION
  3. for /f "delims=" %%c in ('ver')  do (for %%i in (%%c) do (set "verx=%%i"))
  4. for /f "delims=. tokens=1,2,3*" %%f in ("!verx!") do (
  5.         if %%f.%%g equ 5.1 set "verx=WINXP"
  6.         if %%f.%%g equ 6.1 set "verx=WIN7"  
  7.         if %%f.%%g equ 6.2 set "verx=WIN8"
  8.         if %%f.%%g equ 6.3 set "verx=WIN8.1"
  9.         if %%f     equ 10  set "verx=WIN10"
  10. )
  11. set "verx=!verx!.%PROCESSOR_ARCHITECTURE%"
  12. if /i "%PROCESSOR_ARCHITECTURE%"=="AMD64" set verx=!verx:AMD64=X64!
  13. ECHO !verx!
  14. pause
复制代码

作者: nttwqz    时间: 2016-5-30 17:37
dos时代菜鸟 发表于 2016-5-30 06:36
根据 21 楼 代码 简化的:

经过进一步的研究终于系统版本可以用一行命令来获取了

  1. for /f "tokens=1-2 delims=." %%a in ('wmic os get version ^| findstr [0-9]') do echo %%a.%%b
复制代码


在WinXP和Win10上测试通过,vbs我不会,以后有其它需求了,不容易改。

话说,如果尚未安装wmic,即命令行输入wmic会显示正在安装,不知道在批处理中使用wmic会不会收到影响?




欢迎光临 无忧启动论坛 (http://bbs.wuyou.net/) Powered by Discuz! X3.3