|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Что такое текущая директория? |
|
|
Что такое текущая директория?
|
![]() Guest |
Помогите, пожалуйста, начинающему программисту разобраться с понятием текущей директории процесса. Раньше думал, что это каталог, из которого запускается приложение. Однако, сомнение появилось после того, как API-функция GetCurrentDirectory() возвратила "C:\Documents and Settings\имя_учётной_записи" (в Windows XP; реально программа запускалась из другого каталога). Причём это имело место только в случае автозапуска программы из реестра (HKLM\...\Run), при обычном запуске, а также при автозапуске из папки "Автозагрузка" функция возвращала каталог, из которого запускалась программа. Вообще-то вопрос возник после того, как появилась необходимость в программе, стартующей вместе с системой, создать или открыть существующий файл в каталоге программы. Для этого использовалась функция CreateFile(), которой передавалось имя соответствующего файла без пути к нему. Согласно документации файл должен был быть создан в текущей директории - он создавался в "C:\Documents and Settings\имя_учётной_записи". В принципе это не является большой проблемой, т.к. можно, например, запускать программу из папки "Автозагрузка" или использовать функцию GetModuleFileName() с последующим отбрасыванием имени исполняемого файла. Просто хочется узнать, почему так происходит?
|
|
Отправлено: 21:38, 27-01-2003 |
![]() Старожил Сообщения: 240
|
Профиль | Отправить PM | Цитировать Понятие текущая директория - это наследство DOS. Там она отображалась в приглашении командной строки, после выбора диска и нескольких команд cd aaa\bbb, например. Т.е. это та директория на текущем диске, в которую ты вошёл. При наборе имени программы, которую ты хотел бы запустить, DOS сначала искала её в этом каталоге (текущем) или, если не находила, перебирала каталоги, указанные в переменной среды PATH. После того, как программа стартовала, текущий каталог оставался неизменным, а именно тем, в котором ты находиося, запуская программу. Хотя, если в программе были соответствующие вызовы, она могла сменить текущий каталог. Все файлы, открываемые на чтение или запись, брались/создавались в этом каталоге, если путь был указан как относительный, а не абсолютный.
В принципе Win XP тоже сохранила это понятие, хотя в ней трудно оставаться в одном и том же каталоге всё время. Как только ты открываешь (например в проводнике) ещё одну папку, сразу попадаешь в другой каталог, который и становится текущим. А при запуске программы надо рассматривать три вида каталогов - текущий, рабочий и каталог программы. В момент запуска текущим остаётся тот каталог, где ты находился. Но многие программы имеют еще т.н. рабочий каталог, они выдают запрос на смену текущего каталога и делают текущим рабочий. И ещё они точно знают тот каталог, где находится их бинарник. |
------- Отправлено: 02:21, 28-01-2003 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
![]() Guest |
Спасибо за ответ
|
Отправлено: 22:01, 29-01-2003 | #3 |
Модер Сообщения: 1716
|
Профиль | Сайт | Отправить PM | Цитировать Guest
Цитата:
Для каждого процесса есть установленный текущий каталог. Этот каталог, естественно, можно прочитать, сменить и так далее, но обычно сами процессы этим не балуются. Есть набольшие исключения, например, у процесса может не быть текущего каталога по умлочанию и хэндл на него может быть не открыт (см. ниже про PEB). Такие процессы существуют и нормально работают, по всей видимости, запрос текущего каталога для них лмбо обламывается, либо возвращает системый, большего придумать сложно. Но сталкиваться с такими процессами, уверяю, Вам придется ой как нечасто, если вообще придется (хотя, мой TaskEx, если ему указано запускаться под системной учетной записью, запускается с неоткрытым текущим каталогом, да и сам может показать, у кого какой текущий каталог, строка запуска и т.п.). А пока надо запомнить, что у каждого процесса есть свой каталог по умолчанию, абсолютно любой, лишь бы он существовал. На NT-системах это подтверждается форматом PEB (Process Environment Block - блок окружения процесса). За этим отсылаю на свой сайт http://zw.nightmail.ru, где есть краткое описание, что такое TEB и PEB, а также их структура (в описании структур). Обратить внимание надо на PROCESS_PARAMETERS, ссылка на это есть в PEB, так вот, в параметрах процесса хранятся ОТДЕЛЬНЫЕ величины для а) имени запускаемого образа, б) текущего каталога, в)командной строки (обращаю внимание, это полная командная строка, то есть, вообще говоря, в командной строке имя запускаемого файла иожет отсутствовать, она вообще может отсутствовать, как это ни странно) г) пути поиска файлов (в этот путь в коде kernel32.dll насильно добавляется текущий каталог, но в общем случае его там тоже может не быть, как, например, в UNIX-системах из-за соображений безопасности) В принципе, чтоб понять, что это все такое и как оно устроено, надо поглядеть структуру PEB и дочерних структур, и посмотреть TaskEx-ом эти параметры для запущенных в системе процессов и загруженные в них модули. Для проводника переход в другой каталог НЕ приводит к изменению текущего каталога, он просто читает данные из другого каталога, и все. Так что заявления, что трудно оставаться в одном каталоге, мне напоминают заявления о шаловливых ручках, "куда б мне тыкнуться в проводнике"? Да и вообще, в одном процессе проводника может быть несколько окон, отображающих файлы и папки, тут уж явно никакой текущий каталог не поможет. Никаких других каталогов, типа рабочих или программы, не существует. Все, чего нет в PEB - миф. Каталог программы получается из имени образа исполняемого файла, который сохраняется в структурах загрузчика. Откуда запустили - узнать невозможно, можно поглядеть текущий каталог для родительского процесса, но не более того. Вообще, программы запускаются не с диска, а из памяти, так что каталога такого принципиально быть не может. Это все безусловно верно для всех NT-систем. Для 9x - это немного не так, в плане структур и различных тонкостей в случае имени файла и командной строки, но все равно, текущий каталог устанавливается для процесса, а не для окна, он может быть сменен, но не меняется. |
|
------- Отправлено: 17:31, 30-01-2003 | #4 |
![]() Guest |
vasketsov
Теперь Вам спасибо за обстоятельный и, по всей видимости, правильный ответ. Однако, кое-какие вопросы у меня ещё остались (наверное, я тупой ![]() ![]() В связи с вышеобозначенным статусом начинающего программиста мне достаточно сложно разобраться в данном вопросе на низком уровне (хотя абсолютно согласен с тем, что истину можно найти именно там и не только по этому вопросу). Хочу подойти к вопросу с немного другой стороны. В SDK нашёл определение текущего каталога как каталога, из которого запущено приложение, кроме явно изменённого. В то же время одним из параметров функции CreateProcess(), с помощью которой система создаёт новый процесс, является указатель на строку, задающую текущий каталог для создаваемого процесса. Если этот параметр равен NULL, в качестве текущего каталога для нового процесса задаётся текущий каталог родительского процесса. Выходит, что, как Вы и сказали, текущим каталогом для процесса может быть абсолютно любой каталог, указанный родительским процессом. В моём случае функция GetCurrentDirectory() возвратила "C:\Documents and Settings\имя_учётной_записи" при автозапуске программы из реестра. Значит, либо этот каталог явно указан в функции CreateProcess(), либо это текущий каталог родительского (системного) процесса, создающего мой процесс. Возникает вопрос - а почему система не задаёт в качестве текущего каталог, в котором расположен исполняемый файл? Ведь ей известен полный путь к нему, и именно так она поступает в остальных случаях (при автозапуске через папку "Автозагрузка" и при обычном запуске). Почему такое происходит только в случае автозапуска через реестр? |
|
Отправлено: 00:45, 31-01-2003 | #5 |
Модер Сообщения: 1716
|
Профиль | Сайт | Отправить PM | Цитировать Цитата:
Цитата:
Цитата:
2-е - вероятнее всего, ибо запускает процессы оттуда сам Explorer, какой у него текущий каталог? У того Explorer-а им будет папка в профиле, именно та, что Вы указали, правда, я сейчас проверил для internat.exe - там еще добавлен подкаталог с рабочим столом. Цитата:
Вобщем, различие связано с тем, как запускает процессы Explorer. Оно как раз показывает, что пока работает автозагрузка из реестра, текущим каталогом является текущий каталог самого Explorer-а, а при последующих запусках он текущий каталог устанавливает принудительно. Автозагрузка из папки автозагрузки на самом деле реализуется через запуск ярлыка, так что это попадает под то, что выше написано. |
||||
------- Отправлено: 13:31, 31-01-2003 | #6 |
![]() Guest |
vasketsov
А почему бы Explorer'у и в случае автозапуска программы из реестра не установить для неё текущий каталог принудительно? Тот, в котором она находится. Мне кажется, что такое поведение было бы более естественным. Я просто хочу понять, почему Explorer по-разному устанавливает текущий каталог. Может быть из-за дополнительных затрат времени на выделение каталога, в котором находится программа, из пути к исполняемому файлу? Но ведь делает же он это при запуске программы через ярлык. И в каких целях тогда может использовать свой текущий каталог приложение, если вызывающий процесс (в частности Explorer) может установить его любым? Зачем он нужен? А вообще посоветуйте, пожалуйста, хорошую литературу по программированию под Windows (Visual C++, MFC, Win API). Что-нибудь классическое, вроде книги Страуструпа по C++ (если есть такое, конечно ![]() |
Отправлено: 01:08, 01-02-2003 | #7 |
Модер Сообщения: 1716
|
Профиль | Сайт | Отправить PM | Цитировать Guest
1) вопрос не ко мне. 2) До известного уровня системных знаний в Windows - достаточно книг Рихтера. C++ и MFC никакого отношения к Windows не имеют. |
------- Отправлено: 20:58, 01-02-2003 | #8 |
![]() Guest |
vasketsov
Большое спасибо. |
Отправлено: 00:04, 02-02-2003 | #9 |
Serj Mig
Сообщения: n/a |
При работе програмки на Visual C++ функция GetCurrentDirectory возвращает путь расположения exe-шника. Но если после этого вызвать FileDialog и выбрать там файл, расположенный, например, в C:\Мои документы, то после этого GetCurrentDirectory будет возвращать C:\Мои документы.
Подскажите пожалуйста как с этим бороться. Заранее спасибо. |
Отправлено: 18:55, 14-06-2004 | #10 |
|
![]() |
Участник сейчас на форуме |
![]() |
Участник вне форума |
![]() |
Автор темы |
![]() |
Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
что за папка (директория) $OEM$ | Bullet-Avalon | Автоматическая установка Windows 2000/XP/2003 | 1 | 30-11-2008 09:58 | |
Что такое АД? | verdix | Хочу все знать | 2 | 09-06-2008 10:18 | |
Текущая настройка безопасности ActiveX | Motto | Защита компьютерных систем | 1 | 26-12-2004 19:05 | |
Что такое OS/2? | Diesel | Хочу все знать | 3 | 14-03-2003 00:12 |
|