Удалите пробел, наконец, значение свойства WMIC и добавьте еще одну строку - PullRequest
0 голосов
/ 09 июня 2019

Извините за мой плохой английский.Я хочу удалить пробел в последнем значении свойства WMIC и добавить еще одну строку.

del /f /q "GPU.txt"
for /f "skip=2 tokens=2,3,4 delims=," %%a in ('"wmic path Win32_VideoController get Caption,CurrentHorizontalResolution,CurrentVerticalResolution /format:csv"') do (
    SETLOCAL EnableDelayedExpansion
    For %%# in (*) do (
        SET var=%%~n#
        Set MyVar=!var!
        set MyVar=!MyVar: =!
    )
    echo %%a (%%b x !MyVar!)>>"GPU.txt"
)

Ничего не отображать.Спасибо.

1 Ответ

0 голосов
/ 09 июня 2019

Почему этот код не работает?

  1. Пожалуйста, прочитайте этот ответ для получения подробной информации о командах SETLOCAL и ENDLOCAL . При использовании SETLOCAL внутри цикла FOR настоятельно рекомендуется также использовать ENDLOCAL в том же цикле FOR , иначе во время переполнения стека выполнение цикла. Это не происходит здесь, потому что не так много итераций цикла, но все же следует использовать ENDLOCAL в том же цикле FOR , содержащем также SETLOCAL .

  2. For %%# in (*) do в коде вопроса обрабатывает каждое имя файла не скрытых файлов в текущем каталоге. Имя файла без расширения файла присваивается переменной среды var. Затем эта переменная присваивается другой переменной MyVar без каких-либо изменений, за исключением того, что строка Set MyVar=!var! будет содержать конечные пробелы или символы табуляции. И наконец, все пробелы удаляются из строкового значения переменной окружения MyVar, которая является именем файла.

    Понятия не имею, что этот цикл FOR для обработки имен файлов в текущем каталоге связан с именем видеоконтроллера и текущим разрешением по горизонтали и вертикали.

    Я рекомендую прочитать ответ на Почему нет строкового вывода с 'echo% var%' после использования 'set var = text' в командной строке?

  3. Закрывающая круглая скобка ) в командной строке echo %%a (%%b x !MyVar!)>>"GPU.txt" интерпретируется как конец командного блока первого FOR . Необходимо было бы экранировать ) с помощью ^ и использовать echo %%a (%%b x !MyVar!^)>>"GPU.txt", чтобы получить закрывающую скобку, интерпретируемую cmd.exe как буквальный символ, для вывода с помощью echo при разборе всего блока команд, начиная с ( на первом FOR командная строка.

  4. wmic.exe выводит текст UTF-16 Little Endian (два байта на символ) вместо кодированного ANSI (один байт на символ). FOR соответственно cmd.exe имеет ошибку при интерпретации потока символов в кодировке Unicode, как подробно объяснено, например, в Как исправить неправильное поведение при перезаписи переменных при разборе вывода?

    То, что вы считаете пробелом в конце значения вертикального разрешения, в действительности означает возврат каретки, добавленный к этому значению из-за неправильной обработки Unicode-вывода wmic.exe командой FOR соответственно cmd.exe.

Что такое рабочий код и почему он работает?

Одним из возможных решений этой задачи является использование этого кода пакета:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
(for /F "tokens=2-4 delims=," %%I in ('%SystemRoot%\System32\wbem\wmic.exe PATH Win32_VideoController GET Caption^,CurrentHorizontalResolution^,CurrentVerticalResolution /FORMAT:CSV ^| %SystemRoot%\System32\findstr.exe /R ",[0123456789][0123456789]*$"') do (
    set /A CurrentVerticalResolution=%%K
    call echo %%I (%%J x %%CurrentVerticalResolution%%^)
))>"GPU.txt"
endlocal

Вывод Unicode команды инструментария управления Windows перенаправляется на FINDSTR , который фильтрует вывод в строках, заканчивающихся запятой и одной или несколькими цифрами. Таким образом, строка заголовка выхода CSV удаляется, а также строки видеоконтроллера, заканчивающиеся ,, без значений для текущего разрешения по горизонтали и вертикали. Такая строка CSV выводится также на моем компьютере с Windows в дополнение к строке CSV с правильными значениями.

Проблема с неправильным возвратом каретки в конце последнего значения текущего вертикального разрешения остается, несмотря на фильтрацию вывода wmic.exe с findstr.exe.

По этой причине текущее значение вертикального разрешения, назначенное переменной цикла K, не используется напрямую в командной строке echo, поскольку это приведет к ) перезаписи первого символа строки заголовка видеоконтроллера. Используемое здесь решение использует арифметическое выражение для присвоения текущего значения разрешения по вертикали переменной окружения CurrentVerticalResolution. Возврат каретки в конце целочисленного значения интерпретируется как любой другой символ пробела в конце выражения при вычислении арифметического выражения, что означает, что оно игнорируется cmd.exe. Таким образом, переменная окружения CurrentVerticalResolution присвоила значение без нежелательного возврата каретки в конце.

Приведенный выше код позволяет избежать использования SETLOCAL и ENDLOCAL с помощью команды CALL для двойного анализа командной строки echo, как объяснено:

Как интерпретатор сценариев Windows Command Interpreter (CMD.EXE) анализирует?

Командная строка echo с экранированным ) и %%CurrentVerticalResolution%% вместо %CurrentVerticalResolution%уже изменено на строку ниже при первом разборе командной строки echo на cmd.exe перед выполнением команды FOR :

call echo %I (%J x %CurrentVerticalResolution%)

Замена оставшейся ссылки на переменную окружения %CurrentVerticalResolution% замененапо текущему значению этой переменной среды перед выполнением команды ECHO при втором разборе на каждой итерации цикла из-за команды CALL .

Можно также использоватьвнутри цикла FOR :

setlocal EnableDelayedExpansion
echo %%I (%%J x !CurrentVerticalResolution!^)
endlocal
...