batch file - ¿Cómo obtengo Windows cmd FOR para ''jugar bien'' con arrastrar y soltar?
batch-file for-loop (1)
Tenía un guión de lotes muy sencillo. El esquema de diseño es bastante simple ... Quiero tocar cada archivo '' caído ''.
- Hay un atajo de Windows en el escritorio que llama a un script por lotes (.cmd).
- Seleccione algunos archivos con Windows Explorer
- Arrastrar y soltar la selección en el icono de acceso directo o en el archivo de comando directamente.
- La secuencia de comandos pasa por encima de la lista de archivos que se han soltado en el icono.
- La secuencia de comandos usa el comando FOR para llamar al comando un archivo a la vez.
De todos modos, hay varias circunstancias en las que el resultado es extraño (por decir lo menos). El peor ejemplo es un bucle infinito que bloquea cmd.exe. Aquí está el archivo de comando. Hay impresiones y pausas adicionales aquí para poder ver el comportamiento.
@echo off
@title touch
@echo.
cd > z:/$$$/base.tmp
set /p base= < z:/$$$/base.tmp
@rem
@echo ^ folder: %base%
@echo ^ INPUT: [%*]
@echo.
@pause
@echo.
for /d %%x in (%*) DO (
@echo ^ RAW: [%%x]
@echo ^ each --^> [%%~x]
@echo ^ each --^> [%%~fx]
attrib "%%~fx"
touch "%%~fx"
echo.
@pause
echo.
)
@echo.
@echo ^ [done]
@echo.
@pause
La salida más problemática es una fuente de confusión para mí, ver: ejemplo 1. Puse el comando attrib porque es un sistema ''domestico'' .exe.
Cuando comenta el comando "tocar", el aspecto funciona solo con attrib la mayor parte del tiempo. Lo único que puedo decir con certeza es que los nombres de archivo con espacios causan problemas. Por ejemplo, en las líneas " each " de echo-ed, he visto ejemplos como:
-
each --> [Z:/tmp/"Z:/tmp/C++ Recipes.pdf"]
-
"G:/_xfer_/-m"
El primero parece ser un problema con la expansión de bucle FOR y cómo maneja las comillas ("). Mientras que el segundo parece ser un error fuera de límites con el comando MSYS touch.exe.
También hay algo que sucede cuando pasa un archivo de enlace (acceso directo) al script.
He intentado muchas versiones diferentes de la sintaxis FOR y la variable de bucle de escape para dar un paso al costado del problema. Después de todo, mi objetivo principal es tener un comando táctil GUI. Mi primera pregunta para la confianza de los cerebros es:
- ¿Cuál es la expansión FOR y variable de bucle apropiada para usar para esto?
Además, ya que se ha convertido en un misterio ....
- ¿Cómo ocurre el ciclo infinito y hay alguna forma de prevenirlo?
- ¿Alguien tiene un enlace para documentación y / o ejemplos de FOR con un arrastrar y soltar con Ventana?
- ¿Cómo puede la secuencia de comandos mostrar:
Working folder ...
G:/_xfer_
Cuando la cadena: "Carpeta de trabajo", que NO está en la secuencia de comandos .cmd. Y, hubo una vez una versión que tenía el comando:echo Working folder:
Es útil, puse un pequeño script llamado, "drop.cmd" a continuación también. Como punto final, sospecho que hay un error en el controlador de línea de comandos MSYS / GNU para Windows:
- Parece que, cuando el
*args
que se pasó contiene una cadena con comillas no balanceadas - Puede salir de la reserva.
Obtengo un resultado similar al del ejemplo 1, a continuación, de los comandos MSYS touch y tail .
Estaba a punto de cerrar la sesión. Hay una cosa más, a considerar. ¿Alguien tiene un guión o un diagnóstico que pueda usar para ''desenredar'' esta bola de lana ?
Ejemplo 1
folder: G:/_xfer_
INPUT: ["G:/_xfer_/00__zip (on D).lnk" G:/_xfer_/#trash.lnk]
Press any key to continue . . .
RAW: ["G:/_xfer_/00__zip (on D).lnk"]
each --> [G:/_xfer_/00__zip (on D).lnk]
each --> [G:/_xfer_/00__zip (on D).lnk]
A G:/_xfer_/00__zip (on D).lnk
all ... G:/_xfer_/00__zip (on D).lnk
one ... G:/_xfer_/00__zip
two ... (on
Working folder ...
G:/_xfer_
touch -m -c "G:/_xfer_/-m"
Working folder ...
G:/_xfer_
touch -m -c "G:/_xfer_/-m"
:
:
¡Y finalmente se estrelló con un stackoverflow!
drop.cmd
@echo off
@title %~1
@echo.
cd > z:/$$$/base.tmp
set /p base= < z:/$$$/base.tmp
@rem
@echo ^ drop folder: %base%
@echo ^ INPUT: [%*]
@echo.
@pause
rem
@echo.
for %%x in (%*) DO (
@echo ^ RAW: [%%x]
@echo ^ each --^> [%%~x]
@echo.
@pause
)
@echo.
@echo ^ [done]
@echo.
@pause
Obtener un archivo por lotes maneja los archivos eliminados a veces puede ser difícil. Se citará cualquier archivo arrastrado con espacios en su nombre, pero no se citará un archivo con caracteres especiales ( &
) pero sin espacios. Esto dará lugar a problemas con el analizador al manejar los argumentos del archivo usando %*
.
Pero tomando el código de jeb ''answer y pulido por @dbenham para resolver el problema de "Pretty print windows %path%
variable" (gracias a los dos), y recuperando los argumentos de %*
solo cuando se llama desde la línea de comando (donde los argumentos " debería " estar bien formado" o de %cmdcmdline%
(que contiene la línea de comando utilizada para iniciar la instancia de cmd
actual) cuando se descarta, podemos hacer algo como
@echo off
setlocal enableextensions disabledelayedexpansion
set "var="
rem Determine call origin
setlocal enabledelayedexpansion
call :detectDrop !cmdcmdline!
endlocal
if not errorlevel 1 goto :dropped
:commandLine
rem Invoked from command line
set "dropped="
if "%~1"=="" goto done
set var=%*
set "var=%var:"=""%"
goto :process
:dropped
rem Invoked from explorer
set "dropped=1"
set "var=%cmdcmdline:"=""%"
set "var=%var:*/c """"=%"
set "var=%var:*"" =%"
set "var=%var:~0,-2%"
:process
if not defined var goto :done
rem Adapted from dbenham''s answer at [https://.com/a/7940444/2861476]
set "var=%var:^=^^%"
set "var=%var:&=^&%"
set "var=%var:|=^|%"
set "var=%var:<=^<%"
set "var=%var:>=^>%"
set "var=%var: =^ ^ %"
set var=%var:""="%
set "var=%var:"=""Q%"
set "var=%var: ="S"S%"
set "var=%var:^ ^ = %"
set "var=%var:""="%"
setlocal enabledelayedexpansion
set "var=!var:"Q=!"
for %%a in ("!var:"S"S=" "!") do (
if "!!"=="" endlocal
rem Here we have a reference to the passed/dropped element
if %%a neq "" echo "%%~fa"
)
goto :done
:detectDrop cmdcmdline
if /i "%~1"=="%comspec%" if /i "%~2"=="/c" exit /b 0
exit /b 1
:done
if defined dropped ( pause & exit )
nota : lo siento, no probado a fondo. Tal vez haya algún caso que lo haga fallar.