Versión: Windows 10 x64 1909 (español) | Construir: 18363.959
Según Microsoft, el límite del CommandLine
elemento es de 1024 caracteres, pero en mis pruebas, cuando supera los doscientos y tantos caracteres, empieza a comportarse de forma extraña. Teniendo en cuenta que se llama al mismo elemento Path
cuando está en el Microsoft-Windows-Deployment
componente, supongo que la documentación es incorrecta y el límite real es de 259 caracteres para ambos elementos.
Fuentes:
Cómo reproducirse:
En el oobeSystem
pase, agregue estos debajo 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>
El comando 1 se agrega correctamente al registro y se ejecuta:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
Test1 REG_SZ cmd /k echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Pero el comando 2 se agrega HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
literalmente:
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
no muestra nada anormal:
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'
Respuesta1
Recientemente me encontré con el mismo problema y, como habrás adivinado, determiné que el límite era 259 caracteres. Sin embargo, creo que, si se incluyen variables porcentuales en la línea de comando, la expansión de variables puede alterar el límite efectivo. Desgraciadamente, mis pruebas no arrojaron ninguna conclusión definitiva al respecto.
La siguiente prueba sencilla demuestra el límite de 259 caracteres:
<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>
En resumen: la <CommandLine>
línea que tiene 259 caracteres e intenta escribir un archivo llamado 259.log
se escribe con éxito, mientras que la <CommandLine>
línea que tiene 260 caracteres e intenta escribir un archivo llamado 260.log
no.
La primera vez que me encontré con este problema, estaba realizando algunos cambios en las líneas de comando de varias invocaciones de comandos posteriores a la instalación de Windows. Específicamente, mis cambios fueron calificar completamente las rutas de los .exe
archivos y, en algunos casos, usar variables de entorno, por ejemplo, "%ComSpec%"
en lugar de cmd
. ¡Pero al aumentar el número de personajes estaba rompiendo cosas sin darme cuenta!
Lo que resultaba desconcertante era que <CommandLine>
las líneas de menos de 260 caracteres seguían provocando que no se hiciera lo que se suponía que debían hacer. Sabía que los comandos eran correctos porque, sin calificar completamente los .exe
archivos, funcionaban. Aquí hay una <CommandLine>
línea de ejemplo de 253 caracteres que falla:
<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>
Sin embargo, si expando manualmente las variables, entonces mi comando excede el límite de 259 caracteres. Esto podría sugerir que se está produciendo alguna expansión previa de las variables, antes de ejecutar el comando.
Otra observación: intenté correrProcmón, filtrando, por ejemplo, nombre de proceso = cmd.exe
y descubrí que los cmd.exe
comandos que fallaron nunca aparecieron en la salida de Procmon.
Como descubrió, también descubrí que C:\Windows\Panther\UnattendedGC\setupact.log
los informes de que el comando se ejecutó correctamente, independientemente de si lo hizo o no.
Después de leer tu comentario sobre la ejecución desde una memoria USB, parece que estás haciendo algo bastante similar a mí. Una cosa que me ayudó fue establecer una variable de entorno para la letra de la unidad USB. Con suerte, eso le permitirá invocar scripts, en lugar de largas líneas de comando, como usuarioyagmoth555♦comentó. Configuré esto en la <settings pass="specialize">
sección:
<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>
Esto simplemente busca en cada unidad un directorio que se sabe que existe en la memoria USB y, si existe, establece una InstallDrive
variable de entorno en la letra de la unidad con ese directorio. Luego puede hacer referencia %InstallDrive%
más adelante en <settings pass="oobeSystem">
comandos/scripts. Al final de esta sección, elimino la variable de entorno con:
<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>
...sólo para mantener las cosas limpias y ordenadas.
Sé que han pasado cuatro años desde que hizo su pregunta, pero espero que esta respuesta siga siendo relevante para usted y potencialmente para otras personas que hayan enfrentado el mismo problema.