Подтвердить что ты не робот

Обнаружить, если файл bat запущен с помощью двойного щелчка или из окна cmd

У меня есть файл bat, который выполняет кучу вещей и закрывает CMD-окно, которое прекрасно, когда пользователь дважды щелкает файл bat из проводника. Но если я запустил bat файл из уже открытого cmd-окна, как в cmd > c:\myfile.bat, тогда я не хочу, чтобы файл bat файла закрыл окно cmd (END), так как мне нужно делать другие вещи. Мне нужен командный код команды bat dos, который сделает что-то вроде

if (initiated_from_explorer) then
else
endif

Возможно ли это? спасибо

4b9b3361

Ответ 1

%cmdcmdline% дает точную командную строку, используемую для запуска текущего Cmd.exe.

  • При запуске из командной консоли этот параметр "%SystemRoot%\system32\cmd.exe".
  • При запуске из проводника это var cmd /c ""{full_path_to_the_bat_file}" "; это подразумевает, что вы также можете проверить переменную %0 в файле bat, поскольку в этом случае это всегда полный путь к файлу bat и всегда заключен в двойные кавычки.

Лично я бы пошел на подход %cmdcmdline% (не %O), но имейте в виду, что обе команды запуска могут быть переопределены в реестре...

Ответ 2

Решение от "mousio" приятно; однако мне лично не удалось заставить его работать в выражении "IF" из-за двойных кавычек в значении %cmdcmdline% (с двойными кавычками или без них вокруг %cmdcmdline%).

Однако решение, использующее %0, отлично работает. Я использовал следующий оператор блока, и он работает как прелесть:

IF %0 == "%~0"  pause

Надеюсь, это поможет.

Ответ 3

Вы можете добавить параметр командной строки при запуске из окна CMD, которое не будет существовать при двойном щелчке файла. Если параметр отсутствует, закройте окно. Если есть, не закрывайте его. Вы можете проверить параметр с помощью %1

Ответ 4

Это не только возможно, но ваше желаемое поведение - это нормальное поведение исполнения пакетного файла, если вы не сделаете что-то особенное:

  • при выполнении командного файла, дважды щелкнув его в проводнике, окно cmd закроется, когда это будет сделано;
  • когда командный файл выполняется из командной строки, он просто возвращается в командной строке после завершения - окно не закрывается;

Итак, я думаю, что вопрос, на который нужно ответить, - это то, что вы делаете в пакетном файле, который заставляет окно командной строки закрываться при ее выполнении по командной строке?

Ответ 5

Консолидированный ответ, полученный из большей части информации, найденной на этой странице:

:pauseIfDoubleClicked
setlocal enabledelayedexpansion
set testl=%cmdcmdline:"=%
set testr=!testl:%~nx0=!
if not "%testl%" == "%testr%" pause
  • Переменная "testl" получает полную строку вызова процессора cmd (в соответствии с mousio), удаляя все изящные двойные кавычки.
  • Переменная "testr" принимает "testl" и далее выводит имя текущего имени командного файла, если оно присутствует (что будет, если пакетный файл был вызван с помощью двойного щелчка).
  • Оператор if видит, что "testl" и "testr" различны. Если да, пакет был дважды нажат, поэтому пауза; если нет, в командной строке была введена партия, продолжайте.

Естественно, если вы хотите сделать что-то еще, если вы обнаружите двойной щелчок, вы можете изменить паузу.

Спасибо всем.

Ответ 6

Используйте exit /b 0, а не exit

Первый будет завершен полностью, если его запустить из проводника Windows, но верните его в консоль, если он запущен из командной строки.

Ответ 7

Как и @anishsane, мне тоже нужен оператор pause, если он запущен из проводника, но не при запуске из командной строки.

Здесь то, что сработало для меня, основано на @mousio, отвечает выше:

@SET cmdcmdline|FINDSTR /b "cmdcmdline="|FINDSTR /i pushd >nul
@IF ERRORLEVEL 1 (
    @echo.
    @echo Press ENTER when done
    @pause > nul
)

(Ничего оригинального здесь, просто предоставляя рабочий пример)

Ответ 8

Вставьте это в начале вашей BAT или CMD script и, возможно, измените то, что происходит в разделе "if":

:: To leave command window open if script run from Windows explorer.
@setlocal
@set x=%cmdcmdline:"=%
@set x=%x: =%
@set y=%x:cmd/c=%
@if "%x%" neq "%y%" cmd /k %0 %* && exit || exit
@endlocal

Что это значит, если пользователь либо дважды щелкает, либо вызывает этот script, используя "cmd/c", он будет перезапускаться с "cmd/k", который оставит сессию открытой после завершения команды. Это позволяет пользователю ВЫЙТИ или, возможно, сделать что-то еще.

Причина для этого, а не для других способов, объясненных в этом ответе, состоит в том, что я обнаружил ситуации, которые по-прежнему даже с использованием котировок или других символов, оператор IF будет работать с определенными ситуациями в QUOTES и /c и с пробелами. Итак, логика сначала удаляет все ЦИТАТЫ, а затем удаляет все пробелы.. потому что ИМЕЕТСЯ лишнее пространство после удаления кавычек.

set x=%cmdcmdline:"=%       <-- removes all quotes
set x=%x: =%                <-- removes all spaces
set y=%x:cmd/c=%            <-- removes  cmd/c  from the string saving it to  y

Точка && exit || exit - это так, что если ERRORLEVEL до выхода 0 (успех), он прекращает работу, но также, если он не равен 0 (некоторый сбой), он также перестает работать.

Но вы можете заменить эту часть:

cmd /k %0 %* && exit || exit

с чем-то вроде

set CALLED_WITH_CMD_C=YES

а затем создайте свои собственные отличия в остальной части вашего script. Вам нужно будет затем переместить или удалить endlocal.

Символ '@' спереди просто предотвращает эхо, которое вы можете получить, если хотите протестировать. Не используйте эхо-сигнал или эхо-сигнал, так как он изменяет настройку и влияет на все последующие сценарии, которые вызывают.

Ответ 9

@dlchambers был близок, но set не работал, поскольку cmdcmdline не является определенной переменной среды в некоторых случаях, но эта версия основана на его работах, отлично подходит для меня:

echo %cmdcmdline% | findstr /i pushd >nul
if errorlevel 1 pause