Обнаружение, открыт ли файл в командном файле - PullRequest
7 голосов
/ 07 августа 2011

Скажем, у меня есть командный файл для выполнения длинной сборки, и в конце он создает EXE. Если я забуду закрыть приложение перед началом сборки, фаза соединения завершится неудачно, если не удастся заново создать EXE-файл.

Я хочу проверить, открыт ли EXE при запуске сборки. Я попытался переименовать файл EXE для себя, но, хотя это приводит к ошибке отказа в доступе, команда переименования (являющаяся внутренней командой) не устанавливает% ErrorLevel%.

Что такое неразрушающий способ проверки открытого файла, который устанавливает% ErrorLevel% в ненулевое значение?

Ответы [ 3 ]

8 голосов
/ 07 августа 2011

Метод переименования у меня не работал (проверено на Windows XP SP3).Я запустил произвольное приложение и попытался переименовать его себе.Не было ни ошибки, ни эффекта вообще.

Однако этот метод работал:

COPY /B app.exe+NUL app.exe

Когда приложение работало, эта команда выдала мне сообщение об ошибке.И когда приложение было отключено, не только эта команда сохранила содержимое файла, но и оставила временную метку изменения без изменений.

Поэтому на вашем месте я бы, вероятно, использовал эту команду (в началепакетный скрипт, как вы сказали) следующим образом:

COPY /B app.exe+NUL app.exe >NUL || (GOTO :EOF)

Оператор || передает управление команде / блоку рядом с ним, если предыдущая команда завершилась неудачно (подняло значение уровня ошибки).Таким образом, приведенная выше команда завершит выполнение сценария, если COPY не удалась (что было бы, если бы файл был открыт).

Сообщение об ошибке будет сохранено (поскольку такие сообщения обычно отправляются на так называемое стандартное устройство ошибки ине сбрасываются с перенаправлением >NUL, в то время как другие сообщения, не связанные с ошибками, обычно отправляются на стандартный вывод и поэтому могут подавляться с помощью >NUL) и служат объяснением преждевременного завершения сценария.Однако, если вы хотите отобразить собственное сообщение, вы можете попробовать что-то вроде этого:

COPY /B app.exe+NUL app.exe >NUL 2>NUL || (ECHO Target file inaccessible& GOTO :EOF)

В то время как >NUL скрывает все, что отправлено на стандартный вывод, 2>NUL делает то же самое для стандартногоошибка.

1 голос
/ 29 февраля 2016

Нашли лучший способ:

:start
timeout /T 5

if exist %1 (
2>nul (
  >> %1  (call )
) && (goto ende) || (goto start) ) else ( exit )


:ende
YourCode

Это будет проверять каждые 5 секунд на наличие «используется ли файл», если он будет запущен снова. если нет, то получается, что вы можете сделать следующие варианты

1 голос
/ 25 июня 2014
@echo off

:start
ren filename filename        // rename file to same name
if errorlevel 1 goto errorline
echo command successfull file is not in use anymore
goto end
:errorline
echo Rename wasnt possible, file is in use try again in 5seconds
timeout /T 5
goto :start
:end
exit

переименовывает файл с тем же именем, если это возможно, скрипт переходит к концу, который завершает работу с кодом, в противном случае он выдает код ошибки 1 и переходит к строке ошибки, по истечении 5 секунд он переходит к: start и скрипт запускается сначало.

...