Necesito saberlo antes de cualquier intento de hacer algo con dicho archivo.¿Cómo verificar en línea de comandos si un archivo o directorio determinado está bloqueado (utilizado por cualquier proceso)?
Respuesta
No está seguro acerca de los directorios bloqueados
Pero detectar si un archivo se escribe en otro proceso no es difícil.
@echo off
2>nul (
>>test.txt echo off
) && (echo file is not locked) || (echo file is locked)
Utilizo la siguiente secuencia de comandos de prueba desde otra ventana para colocar un bloqueo en el archivo.
(
>&2 pause
) >> test.txt
Cuando ejecuto el segundo guión de una ventana y vuelva a ejecutar la primera secuencia de comandos desde una ventana del segundo, me sale mi mensaje "bloqueado". Una vez que presiono <Enter>
en la primera ventana, aparece el mensaje "desbloqueado" si vuelvo a ejecutar el primer guión.
Explicación
Siempre que la salida de un comando se redirige a un archivo, el archivo, por supuesto, se debe abrir para acceso de escritura. La sesión de Windows CMD intentará abrir el archivo, incluso si el comando no produce ningún resultado.
El operador de redirección >>
abre el archivo en modo de adición.
Así que >>test.txt echo off
intentará abrir el archivo, no escribe nada en el archivo (asumiendo que el eco ya está desactivado), y luego cierra el archivo. El archivo no se modifica de ninguna manera.
La mayoría de los procesos bloquea un archivo cada vez que abren un archivo para acceso de escritura. (Hay llamadas al sistema operativo que permiten abrir un archivo para escribir en un modo compartido, pero ese no es el predeterminado). Entonces, si otro proceso ya tiene bloqueado "test.txt" para la escritura, la redirección fallará y se enviará el siguiente mensaje de error a stderr: "El proceso no puede acceder al archivo porque lo está utilizando otro proceso".. También se generará un código de error cuando falla la redirección. Si el comando y la redirección tienen éxito, se devuelve un código de éxito.
Simplemente agregue 2>nul
al comando no evitará el mensaje de error porque redirige la salida de error para el comando, no la redirección. Es por eso que encierro el comando entre paréntesis y luego redirijo la salida de error a nul fuera de los parens.
De modo que el mensaje de error está efectivamente oculto, pero el código de error aún se propaga fuera de los parens. Los operadores estándar de Windows &&
y ||
se utilizan para detectar si el comando dentro de los parens fue exitoso o no.Es de suponer que echo off
nunca fallará, por lo que la única razón posible de falla sería la redirección fallida. Lo más probable es que falle debido a un problema de bloqueo, aunque técnicamente podría haber otras razones para el fracaso.
Es una "característica" curiosa que Windows no establece la variable dinámica% ERRORLEVEL% en un error al fallar la redirección a menos que se utilice el operador ||
. (Ver File redirection in Windows and %errorlevel%). Por lo tanto, el operador ||
debe leer el código de error devuelto en un nivel bajo, no a través de la variable% ERRORLEVEL%.
Usar estas técnicas para detectar fallas de redirección puede ser muy útil en un contexto por lotes. Se puede usar para establecer bloqueos que permiten la serialización de eventos múltiples en procesos paralelos. Por ejemplo, puede permitir que múltiples procesos escriban de manera segura en el mismo archivo de registro en el "mismo" momento. How do you have shared log files under Windows?
EDITAR
En cuanto carpetas bloqueadas. No estoy seguro de cómo Windows implementa esto, quizás con un bloqueo. Pero si un proceso tiene un directorio activo que involucra la carpeta, entonces la carpeta no puede renombrarse. Que puede ser fácilmente detectado usando
2>nul ren folderName folderName && echo Folder is NOT locked || echo folder is LOCKED
EDITAR
desde entonces he aprendido que (call)
(con un espacio) es un comando muy rápido y sin efectos secundarios que está garantizado para tener éxito con el conjunto ERRORLEVEL a 0. Y (call)
(sin espacio) es un comando rápido sin efectos secundarios que se garantiza que falla con ERRORLEVEL 1.
Así que ahora la siguiente manera para comprobar si un archivo está bloqueado:
2>nul (
>>test.txt (call)
) && (echo file is not locked) || (echo file is locked)
+1 para la sintaxis de cmd puro (¡Todavía estoy tratando de entender cómo y por qué funciona!) –
@Adriano - Explicación agregada :-) – dbenham
¡Genial, lo siento, no puedo votar más de una vez! –
Si descarga e instala el Windows Server 2003 Resource Kit Tools hay una utilidad llamada oh.exe
que enumerará de archivo abierto para un determinado archivo:
http://www.microsoft.com/en-us/download/details.aspx?id=17657
Una vez instalado, reinicie su máquina y podrás usar la utilidad. Puede ver todas las opciones en el Centro de ayuda y soporte técnico y escribir oh /?
en el símbolo del sistema.
(Información de: http://windowsxp.mvps.org/processlock.htm) (? Qué Windows tiene que)
Además de great answer de dbenham, el siguiente formulario finalmente me ayudan a entender la técnica utilizada:
comando(type nul >> file.txt) 2>nul || echo File is locked!
type nul
da una salida vacía y no afecta la configuración de eco actual como echo off
comando en original.
Si desea utilizar if–then–else
condición de recordar el orden correcto - Declaración de éxito (&&
) va primero y declaración alternativa (||
) va en segundo lugar:
command && (echo Command is successful) || (echo Command has failed)
Ten cuidado con el 'if && then || el formato de else, recuerda que el bloque 'else' también se ejecutará si falla el bloque' then'. – remram
Por cierto, la solución de dbenham También parece haber una forma efectiva de averiguar si un proceso se está ejecutando. Fue la mejor solución que encontré para la siguiente aplicación:
start /b "job1.exe >> job1.out"
start /b /wait "job2.exe >> job2.out"
::wait for job1 to finish using dbenham's code to check if job1.out is in use
comparejobs.exe
Nota, la escritura de un mensaje que indica el estado del archivo era menos útil que un comando por lotes que establece un código de retorno. Por ejemplo, devuelve el código 1 si el archivo está bloqueado.
@echo off
2>nul (
>>test.tmp echo off
) && (EXIT /B 0) || (EXIT /B 1)
Sólo quiero compartir con ustedes un ejemplo de mi guión basado en truco de @ dbenham
descripción del script: Check_Locked_Files.bat: Este script puede escanear y comprobar si hay bloqueada archivos en un conjunto de carpetas que se pueden modificar en el script; por ejemplo, he elegido ese conjunto de carpetas para escanear:
Set Folders=^
^ "%ProgramData%\Microsoft\Windows\Start Menu\Programs\Startup"^
^ "%UserProfile%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup"^
^ "%ProgramFiles%\Internet Explorer"^
^ "%ProgramFiles%\Skype"^
^ "%ProgramFiles%\TeamViewer"^
^ "%WinDir%\system32\drivers"^
^ "%Temp%"
El resultado de salida está en formato HTML para una mayor legibilidad.
Si el archivo está bloqueado, lo mostramos en color rojo, de lo contrario, lo mostramos en color verde.
Y toda la secuencia de comandos es: Check_Locked_Files.bat
@echo off
Rem This source is inspired from here
Rem hxxps://stackoverflow.com/questions/
Rem 10518151/how-to-check-in-command-line-if-a-given-file-or-directory-is-locked-used-by-any?answertab=active#tab-top
Rem Thanks for dbenham for this nice trick ;)
Mode con cols=90 lines=5 & color 9E
Title Scan and Check for Locked Files by Hackoo 2017
set "LogFile=%~dp0%~n0.html"
(
echo ^<html^>
echo ^<title^> Scan and Check for locked files by Hackoo 2017^</title^>
echo ^<body bgcolor^=#ffdfb7^>
echo ^<center^>^<b^>Log Started on %Date% @ %Time% by the user : "%username%" on the computer : "%ComputerName%"^</b^>^</center^>
)> "%LogFile%"
echo(
echo --------------------------------------------------------------------------
echo Please Wait a while ....... Scanning for locked files is in progress
echo --------------------------------------------------------------------------
Rem We Play radio just for fun and in order to let the user be patient until the scan ended
Call :Play_DJ_Buzz_Radio
Timeout /T 3 /nobreak>nul
cls
Set Folders=^
^ "%ProgramData%\Microsoft\Windows\Start Menu\Programs\Startup"^
^ "%UserProfile%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup"^
^ "%ProgramFiles%\Internet Explorer"^
^ "%ProgramFiles%\Skype"^
^ "%ProgramFiles%\TeamViewer"^
^ "%WinDir%\system32\drivers"^
^ "%Temp%"
@For %%a in (%Folders%) Do (
(echo ^<hr^>^<font color^=DarkOrange^>^<B^>Folder : %%a^</B^>^</font^>^<hr^>) >> "%LogFile%"
@for /f "delims=" %%b in ('Dir /A-D /s /b "%%~a\*.*"') do (
Call :Scanning "%%~nxb"
Call:Check_Locked_File "%%~b" "%LogFile%"
)
)
(
echo ^<hr^>
echo ^<center^>^<b^>Log ended on %Date% @ %Time% on the computer : "%ComputerName%"^</b^>^</center^>
echo ^</body^>
echo ^</html^>
)>> "%LogFile%"
Start "" "%LogFile%" & Call :Stop_Radio & exit
::***********************************************************************************
:Check_Locked_File <File> <LogFile>
(
2>nul (
>>%1 (call)
) && (@echo ^<font color^=green^>file "%~1"^</font^>^<br^>
) || (
@echo ^<font color^=red^>file "%~1" is locked and is in use^</font^>^<br^>
)
)>>%2 2>nul
exit /b
::***********************************************************************************
:Scanning <file>
cls
echo(
echo --------------------------------------------------------------------------
echo Please Wait a while... Scanning for %1
echo --------------------------------------------------------------------------
exit /b
::***********************************************************************************
:Play_DJ_Buzz_Radio
Taskkill /IM "wscript.exe" /F >nul 2>&1
Set "vbsfile=%temp%\DJBuzzRadio.vbs"
Set "URL=http://www.chocradios.ch/djbuzzradio_windows.mp3.asx"
Call:Play "%URL%" "%vbsfile%"
Start "" "%vbsfile%"
Exit /b
::**************************************************************
:Play
(
echo Play "%~1"
echo Sub Play(URL^)
echo Dim Sound
echo Set Sound = CreateObject("WMPlayer.OCX"^)
echo Sound.URL = URL
echo Sound.settings.volume = 100
echo Sound.Controls.play
echo do while Sound.currentmedia.duration = 0
echo wscript.sleep 100
echo loop
echo wscript.sleep (int(Sound.currentmedia.duration^)+1^)*1000
echo End Sub
)>%~2
exit /b
::**************************************************************
:Stop_Radio
Taskkill /IM "wscript.exe" /F >nul 2>&1
If Exist "%vbsfile%" Del "%vbsfile%"
::**************************************************************
:: Create the file Running.tmp
ECHO %DATE% > Running.tmp
ECHO %TIME% >> Running.tmp
:: block it and do the work
(
>&2 CALL :Work 30
) >> Running.tmp
:: when the work is finished, delete the file
DEL Running.tmp
GOTO EOF
:: put here the work to be done by the batch file
:Work
ping 127.0.0.1 -n 2 -w 1000 > NUL
ping 127.0.0.1 -n %1 -w 1000 > NUL
:: when the process finishes, the execution go back
:: to the line after the CALL
- 1. Cómo verificar si existe un directorio determinado en Ruby
- 2. archivo está siendo utilizado por otro proceso
- 3. ¿Archivo bloqueado por qué proceso?
- 4. ¿Cómo verificar si se está ejecutando un proceso con un PID determinado?
- 5. ¿Cómo verificar si una fecha está en un rango determinado?
- 6. ¿Cómo puedo verificar desde Ruby si se está ejecutando un proceso con un determinado pid?
- 7. Compruebe si un archivo está bloqueado en Java
- 8. ¿Cómo verifico si un archivo está en un directorio determinado, en PowerShell?
- 9. Cómo comprobar si el archivo está siendo utilizado por otro proceso - Powershell
- 10. ¿Cómo verificar si un archivo ya está abierto por otro proceso en C?
- 11. ¿Cómo puedo determinar si un archivo está bloqueado con VBS?
- 12. E/S Java: Asegurar que un archivo no esté bloqueado por otro proceso antes de cualquier operación de r/w
- 13. ¿Cómo puedo desbloquear un archivo que está bloqueado por un proceso en .NET
- 14. C# File.Delete, archivo que está siendo utilizado por otro proceso
- 15. ¿Cómo comprobar si un archivo está abierto por otro proceso (Java/Linux)?
- 16. ¿Cómo elimino un archivo que está bloqueado por otro proceso en C#?
- 17. ¿Cómo verificar si un proceso se está ejecutando con Delphi?
- 18. Lectura de un archivo utilizado por otro proceso
- 19. ¿Cómo abrir un directorio en PHPStorm o IntelliJ (o cualquier JetBrains IDE) desde la línea de comandos?
- 20. proceso no puede acceder al archivo "MyFile.log" porque está siendo utilizado por otro proceso
- 21. ¿Cómo puedo saber si un archivo es descendiente de un directorio determinado?
- 22. Cómo verificar si existe un archivo específico en el directorio o cualquiera de sus subdirectorios
- 23. ¿Cómo verificar si sql_safe_updates está activado?
- 24. ¿Cómo verificar si System.Net.WebClient.DownloadData está descargando un archivo binario?
- 25. Comprobación de PHP si el archivo está bloqueado con flock()?
- 26. Cómo verificar si un DataGridViewCheckBoxCell está marcado
- 27. El proceso no tiene acceso al archivo porque está siendo utilizado por otro proceso
- 28. Dentro de un archivo por lotes, ¿cómo puedo saber si se está ejecutando un proceso?
- 29. C Excepción archivo #: no tiene acceso al archivo porque está siendo utilizado por otro proceso
- 30. ¿Cómo puedo verificar si existe un directorio?
Lo sentimos, pero no puede hacerlo. Desde la línea de comandos no hay forma de saber si un archivo está bloqueado por un proceso (hay que intentar hacer algo con él y "atrapar" el error). –
Creo que PowerShell podría determinar esto. (Estoy empezando a leer Powershell en acción, estoy muy impresionado). En Unix, los archivos bloqueados no son un problema;^/) Buena suerte para todos. – shellter
@Adriano - no es cierto. Ver mi respuesta http://stackoverflow.com/a/10520609/1012053 – dbenham