Версия: Windows 10 x64 1909 (испанский) | Сборка: 18363.959
Согласно Microsoft, ограничение элемента CommandLine
составляет 1024 символа, но в моих тестах, когда он превышает двести с чем-то символов, он начинает вести себя странно. Учитывая, что один и тот же элемент вызывается Path
в Microsoft-Windows-Deployment
компоненте, я предполагаю, что документация неверна, и фактическое ограничение составляет 259 символов для обоих элементов.
Источники:
Как размножать:
В oobeSystem
пропуске добавьте следующее FirstLogonCommands
:
<SynchronousCommand wcm:action="add">
<Order>1</Order>
<Description>Test</Description>
<CommandLine>reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v Test1 /t REG_SZ /d "cmd /k echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" /f</CommandLine>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>2</Order>
<Description>Test</Description>
<CommandLine>reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v Test2 /t REG_SZ /d "cmd /k echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" /f</CommandLine>
</SynchronousCommand>
Команда 1 будет правильно добавлена в реестр и выполнена:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
Test1 REG_SZ cmd /k echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Но команда 2 добавляется HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
буквально:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
Unattend0000000002{373CFC84-60AF-44A4-A316-9BECBAB1AD4B} REG_EXPAND_SZ reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v Test2 /t REG_SZ /d "cmd /k echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" /f
C:\Windows\Panther\UnattendedGC\setupact.log
не показывает ничего аномального:
2020-08-17 19:09:39, Info [Shell Unattend] LogonCommands: Set command 'reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v Test1 /t REG_SZ /d "cmd /k echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" /f'
2020-08-17 19:09:39, Info [Shell Unattend] LogonCommands: Set command 'reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v Test2 /t REG_SZ /d "cmd /k echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" /f'
решение1
Недавно я столкнулся с той же проблемой, и — как вы догадались — я определил предел в 259 символов. Однако я думаю, что — если в командную строку включены процентные переменные — расширение переменной может изменить эффективный предел. К сожалению, мои тесты не дали никаких окончательных выводов в этом отношении.
Следующий простой тест демонстрирует ограничение в 259 символов:
<SynchronousCommand wcm:action="add">
<Order>1</Order>
<RequiresUserInput>false</RequiresUserInput>
<CommandLine>cmd /c ECHO This line will eventually be 259 characters long. This line will eventually be 259 characters long. This line will eventually be 259 characters long. This line will eventually be 259 characters long. This line will even > "C:\Windows\Temp\259.log"</CommandLine>
<Description>259 characters, should produce file</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>2</Order>
<RequiresUserInput>false</RequiresUserInput>
<CommandLine>cmd /c ECHO This line will eventually be 260 characters long. This line will eventually be 260 characters long. This line will eventually be 260 characters long. This line will eventually be 260 characters long. This line will event > "C:\Windows\Temp\260.log"</CommandLine>
<Description>260 characters, should NOT produce file</Description>
</SynchronousCommand>
Короче говоря: <CommandLine>
строка длиной 259 символов, которая пытается записать файл под названием , 259.log
успешно записана, а <CommandLine>
строка длиной 260 символов, которая пытается записать файл под названием , 260.log
— нет.
Впервые я столкнулся с этой проблемой, когда вносил некоторые изменения в командные строки различных вызовов команд после установки Windows. В частности, мои изменения заключались в том, чтобы полностью указать пути к файлам .exe
и в некоторых случаях использовать переменные среды, например, "%ComSpec%"
вместо cmd
. Но, увеличив количество символов, я невольно все сломал!
Что было загадочным, так это то, что <CommandLine>
строки длиной менее 260 символов все еще приводили к сбою в том, что они должны были делать. Я знал, что команды были правильными, потому что без полной квалификации файлов .exe
они работали. Вот пример <CommandLine>
строки из 253 символов, которая дает сбой:
<SynchronousCommand wcm:action="add">
<Order>3</Order>
<RequiresUserInput>false</RequiresUserInput>
<CommandLine>"%ComSpec%" /c FOR %I IN ("%InstallDrive%:\cfs-extras\installers\LibreOffice_*.msi") DO IF NOT DEFINED L "%WinDir%\System32\msiexec.exe" /i "%~fI" /l* "%TMP%\L.log" /qn ALLUSERS=1 CREATEDESKTOPLINK=1 QUICKSTART=1 ADDLOCAL=ALL UI_LANGS=en_GB ^&^& SET L=t</CommandLine>
<Description>Silently install LibreOffice</Description>
</SynchronousCommand>
Однако если я вручную расширяю переменные, то моя команда превышает ограничение в 259 символов! Это может указывать на то, что происходит предварительное расширение переменных до запуска команды.
Еще одно наблюдение: я пробовал бегатьПрокмон, отфильтровав, например, по имени процесса = cmd.exe
и обнаружил, что cmd.exe
команды, которые не были выполнены, никогда не появлялись в выводе Procmon.
Как вы обнаружили, я также обнаружил, что C:\Windows\Panther\UnattendedGC\setupact.log
отчеты об успешном выполнении команды, независимо от того, была ли она выполнена.
Прочитав ваш комментарий о запуске с USB-накопителя, я понял, что вы делаете что-то очень похожее на меня. Мне помогло задание переменной окружения для буквы USB-накопителя. Надеюсь, это позволит вам вызывать скрипты, а не длинные командные строки, как пользовательyagmoth555♦прокомментировал. Я установил это в <settings pass="specialize">
разделе:
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RunSynchronous>
<RunSynchronousCommand wcm:action="add">
<Order>1</Order>
<Description>Set InstallDrive environment variable</Description>
<Path>"%ComSpec%" /c FOR %i IN (C D E F G H I J K L N M O P Q R S T U V W X Y Z) DO IF NOT DEFINED InstallDrive IF EXIST %i:\cfs-extras "%SystemRoot%\System32\setx.exe" InstallDrive %i /M</Path>
</RunSynchronousCommand>
</RunSynchronous>
</component>
Это просто проверяет каждый диск на наличие каталога, который, как известно, существует на USB-накопителе, и если он существует, он устанавливает InstallDrive
переменную окружения на букву диска с этим каталогом. Затем вы можете ссылаться на него %InstallDrive%
позже в <settings pass="oobeSystem">
командах/скриптах. В конце этого раздела я удаляю переменную окружения с помощью:
<SynchronousCommand wcm:action="add">
<Order>7</Order>
<RequiresUserInput>false</RequiresUserInput>
<CommandLine>"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -command [Environment]::SetEnvironmentVariable('InstallDrive',$null,'Machine')</CommandLine>
<Description>Remove InstallDrive machine environment variable. Always run this last.</Description>
</SynchronousCommand>
...просто чтобы поддерживать чистоту и порядок.
Я знаю, что прошло четыре года с тех пор, как вы задали свой вопрос, но я надеюсь, что этот ответ все еще актуален для вас и, возможно, для других, кто столкнулся с той же проблемой.