Пакетный файл, чтобы получить его собственный каталог или каталог, определенный в свойстве ярлыка "Начать с"

Я пишу командный файл на моем компьютере с 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 отделки.

Другие вопросы по тегам