Пакетный файл, чтобы получить его собственный каталог или каталог, определенный в свойстве ярлыка "Начать с"
Я пишу командный файл на моем компьютере с Windows 8.1. В одном разделе моего командного файла мне нужно запустить командную строку в "текущем рабочем каталоге".
Итак, вот как выглядит мой командный файл:
@echo OFF
set WORKING=%cwd%
start cmd.exe /K pushd %WORKING%
exit
Допустим, командный файл находится в папке C: \ Temp \ Utilities. Если я открою окно проводника и дважды щелкните батник, чтобы запустить его, все прекрасно работает. Новая командная строка создается в каталоге C: \ Temp \ Utilities. Однако, если я щелкну правой кнопкой мыши на командном файле и выберу " Запуск от имени администратора", рабочий каталог больше не будет являться местом расположения командного файла, а будет C: \ Windows \ System32.
Точно так же, если я создаю ярлык для командного файла в другой папке (например, C: \ Temp) и повторяю два шага выше, результаты одинаковы. Если бы я дважды щелкнул по ярлыку и запустил его как обычный пользователь, то рабочий каталог - это то, что я ожидал. (Обратите внимание, что рабочий каталог для ярлыка - это все, что установлено для "Начать в" свойств ярлыка, а не местоположение командного файла.) Если я щелкну правой кнопкой мыши по ярлыку и запусту его как администратор, я снова получу открытую командную строку в папку C: \ Windows \ System32.
Я предполагаю, что это "ошибка" или "функция" (если вы хотите так называть) в Windows 8.1, и это, вероятно, происходит из-за того, что среды выполнения для программ, запускаемых от имени администратора, вынуждены запускаться в папке System32? (Я помню, с Windows 7 этого не произошло, поэтому это должно быть новой функцией для Windows 8.)
Я нашел один способ исправить проблему и остановить запуск командной строки в C: \ Windows \ System32. Я сделал это, изменив следующую строку в командном файле:
set WORKING=%~dp0
Делая это таким образом, вы устанавливаете в рабочем каталоге местоположение командного файла. С этим изменением, независимо от того, как я запускаю командный файл или ярлык (администратор или обычный), рабочий каталог остается тем же, C: \ Temp \ Utilities.
Проблема с этим решением в том, что я не хочу, чтобы рабочий каталог всегда был местоположением командного файла. Если пакетный файл запускается напрямую, тогда все в порядке, но если я запускаю его из ярлыка, мне нужно, чтобы рабочий каталог был таким, какой установлен в свойстве "Запускать" этого ярлыка. Например, если командный файл находится в папке D:\Temp\Utilities, это то, что мне нужно, независимо от того, запускаю я от имени администратора или нет:
Shortcut Location Start In Property Command Prompt Working Directory
-------------------- ------------------- ------------------------------------------
C:\Temp <undefined> D:\Temp\Utilities
C:\Data\bin C:\Data\bin C:\Data\bin
C:\Data\bin D:\Temp\Utilities D:\Temp\Utilities
Это означает, что я не всегда могу использовать %~dp0 для установки рабочего каталога в моем командном файле. Мне нужен какой-то способ, чтобы пакетный файл узнал, был ли он запущен напрямую или с помощью ярлыка. Если пакетный файл запускается напрямую, тогда легко получить рабочий каталог, это просто значение % cwd%. Если командный файл запускается с помощью ярлыка, я не знаю, как получить свойство "Начать в" внутри командного файла.
Кто-нибудь знает, как я могу сделать эти две вещи в моем пакетном файле:
1. Проверьте, был ли он запущен напрямую или с помощью ярлыка.
2. При запуске по ярлыку получите свойство "Начать с" ярлыка, который его запустил.
Спасибо,
Orangu
ОБНОВИТЬ
Я нашел своего рода "хакерский" способ исправить проблему. Для ярлыка я отредактировал поле "Цель" и изменил его следующим образом:
cmd.exe /k pushd "C:\Temp" && "D:\Temp\Utilities\batchfile.bat"
Теперь рабочий каталог можно получить, вызвав %CD% в командном файле, и это работает как для администратора, так и для обычных пользователей. Это, однако, не работает для случая, когда я запускаю командный файл напрямую. Мне все еще нужно использовать %~dp0 в этом случае.
Однако мне не нравится это решение, потому что оно требует, чтобы я вручную изменил все созданные мной ярлыки, а также заставляет значок выглядеть как значок приглашения cmd, а не как командный файл.
1 ответ
Вы уже решили не использовать ярлыки вообще?
Вы можете, например, создать batchfile_exec.bat
содержащий ваш звонок
REM optionally do
REM cd /D working_directory
REM if you want to force a special working directory
D:\Temp\Utilities\batchfile.bat
и заменить все ярлыки batchfile_exec.bat
, Если вы дважды щелкните batchfile_exec.bat
рабочий каталог будет содержать batchfile_exec.bat
,
Лично мне не очень нравятся ярлыки Windows, потому что с ними трудно работать в системе контроля версий. Как вы также заметили, если вы хотите изменить многие из них, это займет много времени.
Кстати: если batchfile.bat
был разработан / написан так, чтобы всегда запускаться из директории, где он находится, вы также можете рассмотреть возможность изменения batchfile.bat
чтобы заставить это поведение:
setlocal
cd /D %0\..
REM your original content
endlocal
В %0
путь к пакетному файлу сохраняется.
Хитрость заключается в том, чтобы предположить, что %0
является каталогом, а затем изменить на один уровень ниже на основе этого каталога. С /D
также буква диска изменена правильно.
cd
команда не заботится, если %0
это действительно каталог. по факту %d
даже не должен существовать (%0\dummy\..\..
также будет работать).
setlocal
Команда должна восстановить рабочий каталог, когда batchfile.bat
закончил (это было бы хорошо, если batchfile.bat
был вызван из другого пакетного файла).
Я заметил, что endlocal
В этом контексте команда на самом деле не нужна, так как она применяется неявно, когда batchfile.bat
отделки.