Оптимизация объема кода

Тема в разделе "Пакетные файлы CMD, BAT", создана пользователем Kиpилл, 12 окт 2014.

  1. Kиpилл
    Онлайн

    Kиpилл Команда форума Администратор

    Лучший автор месяца

    Сообщения:
    12.232
    Симпатии:
    4.980
    @Dragokas ты говорил что в отдельной теме можно обсудить кое что.
    Давай.

    Что ты подразумеваешь под этим?

    Ну,и для наглядности даю полностью все,не для того что бы что то изобрести,просто посмотреть что лучше ужать.

    Некоторые идентичные блоки выполняются например разным кодом,чисто потому что пробую что удобнее.
    На данный момент большое желание каждую часть разбивать на блоки (как в примере) что бы было удобно управлять каждым в отдельности,обновлять,переписывать.
    Да и каждый кусок можно отдельным скриптом гонять при поиске ошибок или вариантов.

    Код (DOS):
    @echo off
    Chcp 866 >nul
      title Проверка целостности системных файлов.
       SetLocal EnableExtensions EnableDelayedExpansion

    Call :global

    :setting
    cls
    call :Elevate
    echo Выберите задачу:
    echo (Введите номер и нажите клавишу ENTER)
    echo.
    echo 1. Запустить стандартную проверку
    echo 2. Запустить персональные процедуры восстановления
    echo.
    set choice=
    Set /p choice="Ваш выбор: "
    if not defined choice goto setting
    if "%choice%"=="1" (
                         cls
                         goto recbd )
    if "%choice%"=="2" (
                        cls
                        goto operacion )
    Echo.
    cls
    Echo ═Вы выбрали неверное значение=
    Echo.
    echo.
    echo.
    goto setting

    :global
     
    SET Version=Unknown
    VER | FINDSTR /IL "5.0" > NUL
    IF %ERRORLEVEL% EQU 0 SET Version="Windows 2000"
    VER | FINDSTR /IL "5.1." > NUL
    IF %ERRORLEVEL% EQU 0 SET Version="Windows XP"
    VER | FINDSTR /IL "5.2." > NUL
    IF %ERRORLEVEL% EQU 0 SET Version="Windows 2003"
    VER | FINDSTR /IL "6.0." > NUL
    IF %ERRORLEVEL% EQU 0 SET Version="Windows Vista"
    VER | FINDSTR /IL "6.1." > NUL
    IF %ERRORLEVEL% EQU 0 SET Version="Windows 7"
    VER | FINDSTR /IL "6.2." > NUL
    IF %ERRORLEVEL% EQU 0 SET Version="Windows 8"
    VER | FINDSTR /IL "6.3." > NUL
    IF %ERRORLEVEL% EQU 0 SET Version="Windows 8.1"


    echo.
    echo.


    IF %VERSION% == "Windows XP" GOTO XP
    IF %VERSION% == "Windows 2000" GOTO XP
    IF %VERSION% == "Windows 2003" GOTO XP
    IF %VERSION% == "Windows Vista" GOTO Elevate
    IF %VERSION% == "Windows 7" GOTO Elevate
    IF %VERSION% == "Windows 8" (
                                    Call :setting
                                    GoTo :recbd
                                  )
    IF %VERSION% == "Windows 8.1" (
                                    Call :setting
                                    GoTo :recbd
                                  )
                                   

    GOTO Unknown

    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


    :Elevate

    set log=%windir%\Logs\CBS\sfcdoc.log
    set log2=%windir%\Logs\CBS\sfcdoc2.log
    call :CheckAdmin


    :CheckAdmin
    net session >NUL 2>NUL && (
        > "%log%" (
        echo.
        echo ::::::::  %Userprofile%
        echo ::::::::  %DATE%  / %TIME%
        echo ::::::::  %VERSION%
        echo.
        echo.
        echo :::::::::::::::::::::::::::::::::::::::::::::::::::::
        echo.
        echo ... Права Администратора получены...
        echo .........sfco ErrorLevel [ %ErrorLevel% ]
           )
            ) || (
        echo .........sfco ErrorLevel[ %ErrorLevel% ] >>"%log%"
        Echo Требуются права Администратора.
        Echo.
        echo Необходимо запустить скрипт от имени Администратора
        echo Правой кнопкой мыши по файлу - пункт "Запустить от имени Администратора"
        echo.
        echo Для выхода нажмите клавишу ENTER
        pause>nul
        GoTo Exite
    )
    exit /B
    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

    :WIN7

    cls
    echo Версия Вашей операционной системы: %VERSION%
    echo.
    echo.
    echo ---- _SFC_ ----
    echo.
    echo Если есть установочный диск с версией Вашей Windows вставьте его в дисковод.
    echo.
    echo.
    echo 1. Продолжить проверку без диска
    echo (Введите цифру 1 и нажмите клавишу Enter)
    echo.
    echo 2. Продолжить проверку с диском
    echo (Вставьте диск в дисковод,введите цифру 2 и нажмите клавишу Enter)
    echo.
    GoTo menu

    :menu
    set choice=
    Set /p choice="Ваш выбор: "
    if not defined choice goto menu
    if "%choice%"=="1" ( goto sfco )
    if "%choice%"=="2" ( goto sfco )
    Echo.
    cls
    Echo ═Вы выбрали неверное значение=
    Echo.
    echo.
    echo.
    echo 1. Продолжить проверку без диска
    echo (Введите цифру 1 и нажмите клавишу Enter)
    echo.
    echo 2. Продолжить проверку с диском
    echo ( Вставьте диск в дисковод,введите цифру 2 и нажмите клавишу Enter )
    goto menu




    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::



    :sfco
    echo ::::::::::::::::::::::::::::::::::::::::::::::::::::: >>"%log%"
    Echo. >>"%log%"
    echo ------ SFCDoc parsing ------ >>"%log%"
    cls
    Echo.
    Echo ВНИМАНИЕ!
    Echo.
    Echo Сейчас будет запущена проверка системных файлов на целостность.
    Echo Не выключайте компьютер и не закрывайте окно консоли пока не закончится проверка
    sfc/scannow||(
    echo .........sfco ErrorLevel[ %ErrorLevel% ] >>"%log%"
    cls
    echo Ошибка выполнения скрипта,перезагрузите компьютер и попробуйте снова
    echo запустить скрипт.
    Echo.
    echo Сообщите о проблеме хэлперу .
    echo Нажмите клавишу ENTER что бы продолжить...
    pause > nul
    GoTo exite
    )
    cls
    echo .........sfco ErrorLevel[ %ErrorLevel% ] >>"%log%"
    Echo. >>"%log%"
    Echo. >>"%log%"
    echo.
    echo.
    findstr /c:"[SR]" %windir%\Logs\CBS\CBS.log >>"%log%"

    echo .........findstr ErrorLevel[ %ErrorLevel% ] >>"%log%"

    Echo. >>"%log%"

    explorer.exe %windir%\Logs\CBS\
    Echo ......Открытие папки... >>"%log%"
    Echo. >>"%log%"
    Echo. >>"%log%"
    echo ::::::::::::::::::::::::::::::::::::::::::::::::::::: >>"%log%"
    Echo. >>"%log%"
    echo SafeZone.cc , @ Koza Nozdri >>"%log%"                                
    echo Проверка завершена,теперь откройте папку %windir%\Logs\CBS\
    echo если она не открылась автоматически,
    echo Затем скопируйте в удобное место файл sfcdoc.log
    echo Прикрепите его на форум к вашему сообщению.
    echo.
    Echo Использованы дополнительные параметры: >>"%log%"
    Echo. >>"%log%"
    Echo. >>"%log%"
    Echo | type "%log2%" >>"%log%"
    echo Нажмите клавишу ENTER что бы продолжить...
    pause > nul
    GoTo exite

    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::  

     
    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::                            

                                   
    :XP
    echo Версия Вашей операционной системы: %VERSION%
    for %%i in (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 if exist %%i:\WIN51 set CDROM=%%i:
    if not exist %cdrom%\win51.* (
    echo.
      echo.
       echo.
        cls
         echo Вам необходимо вставить диск с вашей копией Windows
          echo либо смонтировать образ диска в виртуальный привод.& goto cdopen
           ) else (goto koz)


    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::  


    :cdopen
      set m.msg=^
      ДА - Диск с Windows вставлен (или образ смонтирован)^&^
      НЕТ - Выход из программы (ни диска ни образа нет)
      cmd /U /C echo Wscript.Echo Msgbox^(replace^(Wscript.Arguments^(0^),"&",vbLF^),67,"Проверка диска"^)>"msgbox.vbs"
      for /f %%a in ('cscript "msgbox.vbs" "%m.msg%"^& del "msgbox.vbs"') do set err=%%a
      if "%err%"=="2"  goto Exite
      if "%err%"=="6"  goto XP
      if "%err%"=="7"  goto Exite
    goto Exite

    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

    :koz
       echo.
       echo.
       echo Сохраняю резервную копию реестра...
       reg export "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup" %systemdrive%\install.reg
       echo.
       echo Устанавливаю значения реестра...
       echo.
       echo Дистрибутив обнаружен...
       reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup" /v ServicePackSourcePath /t reg_sz /d %cdrom%\ /f
       reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup" /v "Installation Sources" /t reg_sz /d %cdrom%\ /f
       reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup" /v SourcePath /t reg_sz /d %cdrom%\ /f
       sfc/scannow
       reg import %systemdrive%\install.reg
       del /q %systemdrive%\install.reg
       echo.
       echo.
       ping -n 5 127.0.0.1 > NUL
       cls
       echo Проверка целостности системных файлов начата.
       echo Дождитесь окончания проверки.
       ping -n 15 127.0.0.1 > NUL
       goto Exite

    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


                       
                           
                           
    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


    :recbd

    taskkill /f /im "TiWorker.exe"
    (
    >>"%log%" (
    echo ......... Завершение процесса TiWorker.exe [ 0 ] [ успех ]
    echo ......... ErrorLevel[ %ErrorLevel% ]
    echo :::::::::::::::::::::::::::::::::::::::::::::::::::::
    echo.
    echo.
    echo ... Проверка хранилища данных ...
    echo.
        )
         )
    cls
    echo ...Проверяю состояние хранилища данных...
    echo.
    echo.


    echo ...... Проверка состояния компонентов хранилища >>"%log%"
        Dism /Online /Cleanup-Image /CheckHealth
            echo ......... ErrorLevel[ %ErrorLevel% ] >>"%log%"
            if %ErrorLevel% EQU 0 (
            echo ......... Повреждения хранилища компонентов не обнаружены >>"%log%"
            ) else (
            echo. >>"%log%"
            echo ...... Обнаружено повреждение хранилища компонентов >>"%log%"
            )
           
           
    :Clearanalize      
           
    echo. >>"%log%"
    echo. >>"%log%"
    echo.
    echo.
    echo ...... Оценка свободного места хранилища... >>"%log%"
        Dism.exe /Online /Cleanup-Image /AnalyzeComponentStore
            echo ......... ErrorLevel[ %ErrorLevel% ] >>"%log%"
            if %ErrorLevel% EQU 0 (
            echo ......... Требуется очистка WinSxS >>"%log%"
            ) else ( echo ......... Очистка WinSxS не требуется >>"%log%"  )
           
    echo.
    echo.
    echo. >>"%log%"
    echo ::::::::::::::::::::::::::::::::::::::::::::::::::::: >>"%log%"
    echo. >>"%log%"
    echo. >>"%log%"
    ping -n 5 127.0.0.1 > NUL
    GoTo sfco

    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::



    :Restorehealth
    cls

    echo ...... Процедура восстановления хранилища...
    echo ......... Процедура восстановления хранилища... >>"%log2%"
        Dism.exe /Online /Cleanup-Image /Restorehealth
       
            echo ......... ErrorLevel[ %ErrorLevel% ] >>"%log2%"
            if %ErrorLevel% EQU 0 (
            echo ......... Восстановление компонентов хранилища завершено корректно >>"%log2%"      
            ) else (
            echo Восстановление хранилища данных прошло некорректно.
            echo Сообщите о проблеме специалистам SafeZone
            echo ......... Восстановление компонентов хранилища завершено НЕ корректно >>"%log2%" )
           
       
    echo ::::::::::::::::::::::::::::::::::::::::::::::::::::: >>"%log2%"
    echo. >>"%log2%"
    echo. >>"%log2%"
    echo Нажмите клавишу ENTER что бы продолжить
    pause > nul
    exit /b




    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


    :Clearhealth

    cls
    echo ...... Процедура очистки хранилища...
    echo ......... Процедура очистки хранилища... >>"%log2%"
        Dism.exe /Online /Cleanup-Image /StartComponentCleanup
            echo ......... ErrorLevel[ %ErrorLevel% ] >>"%log2%"
            if %ErrorLevel% EQU 0 (
            echo ......... Очистка хранилища завершено корректно >>"%log2%"      
            ) else (
            echo Восстановление хранилища данных прошло некорректно.
            echo Сообщите о проблеме специалистам SafeZone
            echo ......... Восстановление компонентов хранилища завершено НЕ корректно >>"%log2%" )
           
       
    echo ::::::::::::::::::::::::::::::::::::::::::::::::::::: >>"%log2%"
    echo. >>"%log2%"
    echo. >>"%log2%"
    echo Нажмите клавишу ENTER что бы продолжить
    pause > nul
    exit /b

    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::  

         

    :operacion

    echo ::::::::::::::::::::::::::::::::::::::::::::::::::::: >"%log2%"
    echo. >>"%log2%"
    echo. >>"%log2%"
    echo ::::::::  %Userprofile%  >>"%log2%"
    echo ::::::::  %DATE%  / %TIME%  >>"%log2%"
    echo Персональные процедуры восстановления >>"%log2%"
    echo. >>"%log2%"

    taskkill /f /im "TiWorker.exe"
    echo ......... Завершение процесса TiWorker.exe [ 0 ] [ успех ] >>"%log2%"
    echo ......... ErrorLevel[ %ErrorLevel% ] >>"%log2%"
    cls

    call :choice "Восстановление хранилища данных" "Очистка хранилища данных" "Очистка и восстановление хранилища данных" "Главное меню"

    if %ErrorLevel% EQU 1 ( Call :Restorehealth
                            GoTo setting)
    if %ErrorLevel% EQU 2 ( Call :Clearhealth
                            GoTo setting)
    if %ErrorLevel% EQU 3 ( Call :Restorehealth
                            Call :Clearhealth
                            GoTo setting)
    if %ErrorLevel% EQU 4 ( GoTo setting )


    :choice
    setlocal
    if "%~1"=="" (
      set result=0
      pause
      goto choice_3
    )
    set count=0
    :choice_1
    set /a count+=1
    echo %count%. %~1
    shift
    if not "%~1"=="" goto choice_1
    :choice_2
    set /p result=Выш выбор (1-%count%):
    for /l %%i in (1, 1, %count%) do if "%result%"=="%%i" goto choice_3
    goto choice_2
    :choice_3
    endlocal & exit /b %result%

    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

     
    :Exite
    cls
      Echo ====== Работа скрипта завершена ======
      Echo.
      Echo.
      Echo Скрипт подгтовлен Koza Nozdri
      Echo Сайт: SafeZone.cc
      Echo E-mail: Fire@safezone.cc
      Echo.
      Echo======================================================================
      Echo Бесплатное лечение компьютерных вирусов и решение проблем в работе ПК
        ping -n 15 127.0.0.1 > NUL
      Exit

    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

     
    :UNKNOWN
    cls
    Echo =====  ERROR!  =====
    Echo Данный скрипт не предназначен для Вашей операционной системы,
    Echo воспользуйтесь соответствующим версии Вашей операционной системs сценарием
    Echo или обратитесь за помощью на форум: SafeZone.cc
    ping -n 10 127.0.0.1 > NUL
    Exit
     
     
  2. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.497
    Симпатии:
    4.312
    Привет.

    Допустим у тебя идет начало кода.
    И тебе хочется узнать версию ОС и дальше от нее плясать - выполнить ту или другую метку.
    Тебе вообще не нужны операторы Goto.

    Код (DOS):

    @echo off
    Chcp 866 >nul
    title Проверка целостности системных файлов.
    SetLocal EnableExtensions EnableDelayedExpansion

    :: Все основные переменные принято указывать в самом начале:

    set log=%windir%\Logs\CBS\sfcdoc.log
    set log2=%windir%\Logs\CBS\sfcdoc2.log

    :: Получаем в переменную версию ОС

    :: В isVistaOrLater получаем true, если ОС - Виста или выше.
    call :GetOSVersion || exit /B

    :: Теперь мы можем определить, в какую ветвь кода перейти, т.к. у нас есть переменные Version и isVistaOrLater

    :: Сначала проверим права.
    if "%isVistaOrLater%"=="true" call :CheckAdmin || exit /B

    :: Заметь, что в конце подпрограммы :CheckAdmin я поставил Exit /B 1.

    :: Это значит, что при неудаче проверки вернется не-нулевой код возврата
    :: и сработает || после которого идет Exit /B, а значит завершится работа этого скрипта и только 1 текущей сессии работы интерпретатора,
    :: а не всей программы CMD, если мне например захочется твой скрипт запустить не двойным кликом, а через CMD.exe.
    :: Не забывай, что в 10-ке вообще хотят сделать несколько вкладок в CMD. Что если твоя прога закроет их все ? Поэтому, только Exit /B

    call :main_menu
    goto :eof


    :GetOSVersion
        VER | FINDSTR /IL "5.0" > NUL
        IF %ERRORLEVEL% EQU 0 SET Version="Windows 2000"
        VER | FINDSTR /IL "5.1." > NUL
        IF %ERRORLEVEL% EQU 0 SET Version="Windows XP"
        VER | FINDSTR /IL "5.2." > NUL
        IF %ERRORLEVEL% EQU 0 SET Version="Windows 2003"
        VER | FINDSTR /IL "6.0." > NUL
        IF %ERRORLEVEL% EQU 0 (SET Version="Windows Vista"& set isVistaOrLater = true)
        VER | FINDSTR /IL "6.1." > NUL
        IF %ERRORLEVEL% EQU 0 (SET Version="Windows 7"& set isVistaOrLater = true)
        VER | FINDSTR /IL "6.2." > NUL
        IF %ERRORLEVEL% EQU 0 (SET Version="Windows 8"& set isVistaOrLater = true)
        VER | FINDSTR /IL "6.3." > NUL
        IF %ERRORLEVEL% EQU 0 (SET Version="Windows 8.1"& set isVistaOrLater = true)
        VER | FINDSTR /IL "6.4." > NUL
        IF %ERRORLEVEL% EQU 0 (SET Version="Windows 10"& set isVistaOrLater = true)
        if not defined Version (call :Unknown & exit /B 1)
    Exit /B

    :CheckAdmin
      net session >NUL 2>NUL && (
        > "%log%" (
        echo.
        echo ::::::::  %Userprofile%
        echo ::::::::  %DATE%  / %TIME%
        echo ::::::::  %VERSION%
        echo :::::::::::::::::::::::::::::::::::::::::::::::::::::
        echo ... Права Администратора получены...
        echo .........sfco ErrorLevel [ %ErrorLevel% ]
           )
            ) || (
        echo .........sfco ErrorLevel[ %ErrorLevel% ] >>"%log%"
        Echo Требуются права Администратора.
        Echo.
        echo Необходимо запустить скрипт от имени Администратора
        echo Правой кнопкой мыши по файлу - пункт "Запустить от имени Администратора"
        echo.
        echo Для выхода нажмите клавишу ENTER
        pause>nul
        call :Exite
        exit /B 1
      )
    exit /B

    :main_menu
    cls
    echo Выберите задачу:
    echo (Введите номер и нажмите клавишу ENTER)
    echo.
    echo 1. Запустить стандартную проверку
    echo 2. Запустить персональные процедуры восстановления
    echo.
    set choice=
    set /p choice="Ваш выбор: "
    if "%choice%"=="1" (
                         cls
                         call :recbd )
    if "%choice%"=="2" (
                        cls
                        call :operacion )
    goto main_menu
     
     
    Последнее редактирование: 12 окт 2014
  3. Гимаев Наиль
    Оффлайн

    Гимаев Наиль Пользователь

    Сообщения:
    59
    Симпатии:
    98
    Когда выполняется команда call, запускается второй интерпретатор cmd, но в том же процессе cmd.exe, что и первый.
    Получается, что в памяти как бы две копии одного батника. Только один выполняется с первой строки, а другой с метки.
    goto не закрывает текущий интерпретатор, вот к чему это может привести:
    Код (DOS):
    call :test1
    echo I'm still working
    :back
    echo I'm work
    exit /b

    :test1
    goto :back
    Интересное поведение можно обнаружить если изменять батник с call в процессе исполнения. Допустим, запустили батник на исполнение. И если поменять какую-то строку до того, как она выполнится, то изменения будут проигнорированы, т.к. батник исполняется из памяти, а не с диска. Но если исправленая строка находится в блоке вызываемом через call, то изменения будут учтены в полной мере. Об этом полезно знать, если делать самомодифицирующийся батник.
     
    Последнее редактирование: 13 окт 2014
    Alex1983, Dragokas и Kиpилл нравится это.
  4. Гимаев Наиль
    Оффлайн

    Гимаев Наиль Пользователь

    Сообщения:
    59
    Симпатии:
    98
    Хотя результат выполнения батника очевиден, но я всё таки напишу его для тех, кому некогда его запустить:
    Код (Text):
    I'm work
    I'm still working
    I'm work
    А заодно и правильный вариант:
    Код (DOS):

    call :test1
    echo I'm still working
    exit /b

    :test1
    echo I'm work
    exit /b
     
     
    Последнее редактирование: 13 окт 2014
  5. Kиpилл
    Онлайн

    Kиpилл Команда форума Администратор

    Лучший автор месяца

    Сообщения:
    12.232
    Симпатии:
    4.980
    Прочитал,видимо много еще раз переделаю)
    Покажу.
     
  6. Kиpилл
    Онлайн

    Kиpилл Команда форума Администратор

    Лучший автор месяца

    Сообщения:
    12.232
    Симпатии:
    4.980
    В итоге получилось треть скрипта упразднить,он стал легче и логичнее:

    Код (DOS):
    Call :veros
    exit /b

    :setting

    call :Elevate

    cls
    echo Для выбора введите цифру и нажмите клавишу ENTER
    echo.
    echo.

    call :choice "Запустить стандартную проверку" "Запустить персональные процедуры восстановления" "Выход"

    if %ErrorLevel% EQU 1 ( Call :recbd )
                                     
    if %ErrorLevel% EQU 2 ( Call :operacion )
                                     
    if %ErrorLevel% EQU 3 ( Call :Exite )
                                       
    exit /b





    :veros

    SET Version=Unknown

    VER | FINDSTR /IL "5.0" > NUL
    IF %ERRORLEVEL% EQU 0 ( SET Version="Windows 2000" )

    VER | FINDSTR /IL "5.1." > NUL
    IF %ERRORLEVEL% EQU 0 ( SET Version="Windows XP" )

    VER | FINDSTR /IL "5.2." > NUL
    IF %ERRORLEVEL% EQU 0 ( SET Version="Windows 2003" )

    VER | FINDSTR /IL "6.0." > NUL
    IF %ERRORLEVEL% EQU 0 ( SET Version="Windows Vista"
                                                set os=1
                                                    call :setting )
    VER | FINDSTR /IL "6.1." > NUL
    IF %ERRORLEVEL% EQU 0 ( SET Version="Windows 7"
                                                set os=1
                                                    call :setting )            
    VER | FINDSTR /IL "6.2." > NUL
    IF %ERRORLEVEL% EQU 0 ( SET Version="Windows 8"
                                                set os=0
                                                     call :setting )
                                                                 
    VER | FINDSTR /IL "6.3." > NUL
    IF %ERRORLEVEL% EQU 0 ( SET Version="Windows 8.1"
                                                 set os=0
                                                      call :setting )


                                                   
    exit /b
                                                                 
     
     
    Последнее редактирование: 21 окт 2014
  7. Гимаев Наиль
    Оффлайн

    Гимаев Наиль Пользователь

    Сообщения:
    59
    Симпатии:
    98
    Код (DOS):
    VER | FINDSTR /IL "5.0" > NUL
    IF %ERRORLEVEL% EQU 0 ( SET Version="Windows 2000" )
    Возможно я не прав (нужно перепроверить), но мне кажется, что правильнее записать так:
    Код (DOS):
    (VER | FINDSTR /IL "5.0" > NUL)&&(SET Version="Windows 2000" )
     
    Dragokas нравится это.
  8. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.497
    Симпатии:
    4.312
    Да. Только последнюю скобку нужно без пробела.

    Но лично я бы с учетом эстетической красоты написал бы примерно так:
    Код (Text):
    :veros
    SET "Version=Unknown"
    VER | FINDSTR /IL "5.0" > NUL  &&  SET "Version=Windows 2000"||(
    VER | FINDSTR /IL "5.1." > NUL &&  SET "Version=Windows XP"||(
    VER | FINDSTR /IL "5.2." > NUL &&  SET "Version=Windows 2003"||(
    VER | FINDSTR /IL "6.0." > NUL && (SET "Version=Windows Vista"& set os=1& call :setting)||(
    VER | FINDSTR /IL "6.1." > NUL && (SET "Version=Windows 7"    & set os=1& call :setting)||(
    VER | FINDSTR /IL "6.2." > NUL && (SET "Version=Windows 8"    & set os=0& call :setting)||(
    VER | FINDSTR /IL "6.3." > NUL && (SET Version="Windows 8.1"  & set os=0& call :setting
    )))))))
    echo %Version%
    pause
    --- Объединённое сообщение, 4 ноя 2014 ---
    Странно, какой-то баг движка редактора:
    Код (DOS):

    :veros
    SET "Version=Unknown"
    VER | FINDSTR /IL "5.0" > NUL  &&  SET "Version=Windows 2000"||(
    VER | FINDSTR /IL "5.1." > NUL &&  SET "Version=Windows XP"||(
    VER | FINDSTR /IL "5.2." > NUL &&  SET "Version=Windows 2003"||(
    VER | FINDSTR /IL "6.0." > NUL && (SET "Version=Windows Vista"& set os=1& call :!!)||(
    VER | FINDSTR /IL "6.1." > NUL && (SET "Version=Windows 7"    & set os=1& call :!!)||(
    VER | FINDSTR /IL "6.2." > NUL && (SET "Version=Windows 8"    & set os=0& call :!!)||(
    VER | FINDSTR /IL "6.3." > NUL && (SET Version="Windows 8.1"  & set os=0& call :setting
    )))))))
    echo %Version%
    pause
     
     
    Гимаев Наиль и Kиpилл нравится это.
  9. Гимаев Наиль
    Оффлайн

    Гимаев Наиль Пользователь

    Сообщения:
    59
    Симпатии:
    98
    Лично меня смущает многократное повторение VER | FINDSTR /IL "5.0"
    Команда VER быстрая, а её вывод короткий, поэтому FINDSTR тоже выполнит свою работу быстро, но я бы сначала поместил величину в переменную, а потом использовал бы массив: http://www.cyberforum.ru/cmd-bat/thread672170.html#post3576648
    Правда, тогда код стал бы менее понятным.
    --- Объединённое сообщение, 4 ноя 2014, Дата первоначального сообщения: 4 ноя 2014 ---
    Я немного подумал и пришёл к выводу, что вообще не стал бы заморачиваться с преобразованием числовой версии в текстовую.
    Во-первых, поместил бы в переменную номер версии из команды:
    Код (DOS):
    reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion" /v "CurrentVersion"
    А название версии взял бы из из
    Код (DOS):
    reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion" /v "ProductName"
    Все переходы делал бы по номеру версии, а для вывода информации использовал бы текстовую версию.
     
  10. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.497
    Симпатии:
    4.312
    Здесь + в том, что вывод ver постоянен, а значение в реестре может быть и испорчено (кем-то случайно или специально).
    На счет парсинга ver с проходом через массив: в XP ее вывод немного отличается от вывода в других версиях ОС. Это придется учитывать.
     
  11. Kиpилл
    Онлайн

    Kиpилл Команда форума Администратор

    Лучший автор месяца

    Сообщения:
    12.232
    Симпатии:
    4.980
    Что наблюдалось при некоторых наших разработках... в итоге версия определялась неверно.
    Я сейчас хочу вообще уйти от ver ,но не определять данные через реестр.
    В новой весии кода будет определение точной версии системы и архитектуры.
     
  12. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.497
    Симпатии:
    4.312
    Можно поинтересоваться каким методом будет реализовано?
     
  13. Гимаев Наиль
    Оффлайн

    Гимаев Наиль Пользователь

    Сообщения:
    59
    Симпатии:
    98
    Всегда считал, что Ver берёт информацию из реестра. Оказывается версия берётся из ресурсов файла C:\Windows\Branding\Basebrd\basebrd.dll
    Так что и ver можно обмануть, но сделать это не так просто как поменять пару строчек в реестре.
     
    Dragokas нравится это.
  14. Kиpилл
    Онлайн

    Kиpилл Команда форума Администратор

    Лучший автор месяца

    Сообщения:
    12.232
    Симпатии:
    4.980
    Я пока не смог это собрать во внятные мысли.
     
  15. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.497
    Симпатии:
    4.312
    Я думал ты как-то тоже по версии файла смотреть хочешь. Это умеет makecab.
    Код (Text):

    @echo off
    SetLocal EnableExtensions
    call :GetFileInfo "%SystemRoot%\Branding\Basebrd\basebrd.dll" "*ver*" FileVer
    echo %FileVer%
    pause
    exit /B

    :GetFileInfo [_in_ FullFileName] [_in_ Type of Information] [_out_ Variable, that receive a bufer]
      :: Функция получения версии файла
      set "%~3=" & pushd "%~dp1" & echo "%~nx1"> "%TEMP%\file.path"
      (echo .set DoNotCopyFiles=on&echo .Set Cabinet=off&echo .Set Compress=off&echo .Set InfFileLineFormat="%~2") > "%TEMP%\cab.inf"
      makecab /d InfFileName="%TEMP%\file.inf" /d "DiskDirectory1=%TEMP%" /f "%TEMP%\cab.inf" /f "%TEMP%\file.path" /v0 >NUL
      for /f "usebackq skip=4 delims=" %%f in ("%TEMP%\file.inf") do set "%~3=%%f"
      (del /f "%TEMP%\file.inf" & del /f "%TEMP%\file.path" & del /f "%TEMP%\cab.inf" & del "%~dp1\setup.rpt") 2>NUL & popd
    exit /B
     
     
    Kиpилл нравится это.
  16. Kиpилл
    Онлайн

    Kиpилл Команда форума Администратор

    Лучший автор месяца

    Сообщения:
    12.232
    Симпатии:
    4.980
    Да,по манифесту или файлу.
    У кстати - спасибы за пример)
     
  17. Гимаев Наиль
    Оффлайн

    Гимаев Наиль Пользователь

    Сообщения:
    59
    Симпатии:
    98
    Я слегка озадачен. С одной стороны и ver и winver обращаются к библиотеке basebrd.dll, но при этом информация о версии dll ни как не используется (проверял через подмену версии). Я предполагал, что данные хранятся в ресурсах библиотеки, но ресурс RES_METADATA не содержит ни чего похожего на номер версии. К тому же там данные двоичные, т.е. их нельзя просто извлечь и использовать. По соседству имеется файл basebrd.dll.mui, с текстовыми названиями версий (всех версий). В общем, мне не удалось понять где и в каком виде хранится версия windows, но точно не в версии dll.
     

Поделиться этой страницей