Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Что такое текущая директория?

Ответить
Настройки темы
Что такое текущая директория?

Аватара для Guest

Guest



Профиль | Цитировать


Помогите, пожалуйста, начинающему программисту разобраться с понятием текущей директории процесса. Раньше думал, что это каталог, из которого запускается приложение. Однако, сомнение появилось после того, как API-функция GetCurrentDirectory() возвратила "C:\Documents and Settings\имя_учётной_записи" (в Windows XP; реально программа запускалась из другого каталога). Причём это имело место только в случае автозапуска программы из реестра (HKLM\...\Run), при обычном запуске, а также при автозапуске из папки "Автозагрузка" функция возвращала каталог, из которого запускалась программа. Вообще-то вопрос возник после того, как появилась необходимость в программе, стартующей вместе с системой, создать или открыть существующий файл в каталоге программы. Для этого использовалась функция CreateFile(), которой передавалось имя соответствующего файла без пути к нему. Согласно документации файл должен был быть создан в текущей директории - он создавался в "C:\Documents and Settings\имя_учётной_записи". В принципе это не является большой проблемой, т.к. можно, например,  запускать программу из папки "Автозагрузка" или использовать функцию GetModuleFileName() с последующим отбрасыванием имени исполняемого файла. Просто хочется узнать, почему так происходит?

Отправлено: 21:38, 27-01-2003

 

Аватара для shurikan

Старожил


Сообщения: 240
Благодарности: 1

Профиль | Отправить PM | Цитировать


Понятие текущая директория - это наследство DOS. Там она отображалась в приглашении командной строки, после выбора диска и нескольких команд cd aaa\bbb, например. Т.е. это та директория на текущем диске, в которую ты вошёл. При наборе имени программы, которую ты хотел бы запустить, DOS сначала искала её в этом каталоге (текущем) или, если не находила, перебирала каталоги, указанные в переменной среды PATH. После того, как программа стартовала, текущий каталог оставался неизменным, а именно тем, в котором ты находиося, запуская программу. Хотя, если в программе были соответствующие вызовы, она могла сменить текущий каталог. Все файлы, открываемые на чтение или запись, брались/создавались в этом каталоге, если путь был указан как относительный, а не абсолютный.
В принципе Win XP тоже сохранила это понятие, хотя в ней трудно оставаться в одном и том же каталоге всё время. Как только ты открываешь (например в проводнике) ещё одну папку, сразу попадаешь в другой каталог, который и становится текущим. А при запуске программы надо рассматривать три вида каталогов - текущий, рабочий и каталог программы. В момент запуска текущим остаётся тот каталог, где ты находился. Но многие программы имеют еще т.н. рабочий каталог, они выдают запрос на смену текущего каталога и делают текущим рабочий. И ещё они точно знают тот каталог, где находится их бинарник.

-------
UNIX, UNAS и др. Myself I'll like 'em


Отправлено: 02:21, 28-01-2003 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

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


Аватара для Guest

Guest


Профиль | Цитировать


Спасибо за ответ

Отправлено: 22:01, 29-01-2003 | #3


Модер


Сообщения: 1716
Благодарности: 17

Профиль | Сайт | Отправить 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 - это немного не так, в плане структур и различных тонкостей в случае имени файла и командной строки, но все равно, текущий каталог устанавливается для процесса, а не для окна, он может быть сменен, но не меняется.

-------
Васкецов Сергей
http://registry.oszone.net


Отправлено: 17:31, 30-01-2003 | #4


Аватара для Guest

Guest


Профиль | Цитировать


vasketsov
Теперь Вам спасибо за обстоятельный и, по всей видимости, правильный ответ. Однако,  кое-какие вопросы у меня ещё остались (наверное, я тупой ... или самокритичный ).

В связи с вышеобозначенным статусом начинающего программиста мне достаточно  сложно разобраться в данном вопросе на низком уровне (хотя абсолютно согласен с тем,  что истину можно найти именно там и не только по этому вопросу). Хочу подойти к  вопросу с немного другой стороны. В SDK нашёл определение текущего каталога как  каталога, из которого запущено приложение, кроме явно изменённого. В то же время  одним из параметров функции CreateProcess(), с помощью которой система создаёт  новый процесс, является указатель на строку, задающую текущий каталог для  создаваемого процесса. Если этот параметр равен NULL, в качестве текущего каталога  для нового процесса задаётся текущий каталог родительского процесса. Выходит, что,  как Вы и сказали, текущим каталогом для процесса может быть абсолютно любой каталог,  указанный родительским процессом. В моём случае функция GetCurrentDirectory()  возвратила "C:\Documents and Settings\имя_учётной_записи" при автозапуске программы  из реестра. Значит, либо этот каталог явно указан в функции CreateProcess(), либо это  текущий каталог родительского (системного) процесса, создающего мой процесс.  Возникает вопрос - а почему система не задаёт в качестве текущего каталог, в котором  расположен исполняемый файл? Ведь ей известен полный путь к нему, и именно так она  поступает в остальных случаях (при автозапуске через папку "Автозагрузка" и при  обычном запуске). Почему такое происходит только в случае автозапуска через реестр?

Отправлено: 00:45, 31-01-2003 | #5


Модер


Сообщения: 1716
Благодарности: 17

Профиль | Сайт | Отправить PM | Цитировать


Цитата:
В SDK нашёл определение текущего каталога как  каталога, из которого запущено приложение, кроме явно изменённого
Это неверное определение, может SDK старый?

Цитата:
В то же время  одним из параметров функции CreateProcess(), с помощью которой система создаёт  новый процесс, является указатель на строку, задающую текущий каталог для  создаваемого процесса. Если этот параметр равен NULL, в качестве текущего каталога  для нового процесса задаётся текущий каталог родительского процесса
Да, это верно. Правда, это не система так делает, а реализуется в функции CreateProcess и тех функциях, что вызываются из нее. Если при непосредственном создании процесса указать, что у него текущий каталог NULL - так оно и будет.

Цитата:
функция GetCurrentDirectory()  возвратила "C:\Documents and Settings\имя_учётной_записи" при автозапуске программы  из реестра. Значит, либо этот каталог явно указан в функции CreateProcess(), либо это  текущий каталог родительского (системного) процесса, создающего мой процесс
1-е - вряд ли.
2-е - вероятнее всего, ибо запускает процессы оттуда сам Explorer, какой у него текущий каталог? У того Explorer-а им будет папка в профиле, именно та, что Вы указали, правда, я сейчас проверил для internat.exe - там еще добавлен подкаталог с рабочим столом.

Цитата:
Возникает вопрос - а почему система не задаёт в качестве текущего каталог, в котором  расположен исполняемый файл?
Еще раз, система сама это не делает, это устанавливаетс запускающая программа. Если из проводника даблкликом запускать процесс, то Explorer запускает его с тем текущим каталогом, что открыт (если только не нашелся ярлык, корректирующий запуск, например, pif).

Вобщем, различие связано с тем, как запускает процессы Explorer. Оно как раз показывает, что пока работает автозагрузка из реестра, текущим каталогом является текущий каталог самого Explorer-а, а при последующих запусках он текущий каталог устанавливает принудительно.

Автозагрузка из папки автозагрузки на самом деле реализуется через запуск ярлыка, так что это попадает под то, что выше написано.

-------
Васкецов Сергей
http://registry.oszone.net


Отправлено: 13:31, 31-01-2003 | #6


Аватара для Guest

Guest


Профиль | Цитировать


vasketsov
А почему бы Explorer'у и в случае автозапуска программы из реестра не установить для  неё текущий каталог принудительно? Тот, в котором она находится. Мне кажется, что  такое поведение было бы более естественным. Я просто хочу понять, почему Explorer  по-разному устанавливает текущий каталог. Может быть из-за дополнительных затрат  времени на выделение каталога, в котором находится программа, из пути к исполняемому  файлу? Но ведь делает же он это при запуске программы через ярлык. И в каких целях  тогда может использовать свой текущий каталог приложение, если вызывающий процесс  (в частности Explorer) может установить его любым? Зачем он нужен?

А вообще посоветуйте, пожалуйста, хорошую литературу по программированию под  Windows (Visual C++, MFC, Win API). Что-нибудь классическое, вроде книги Страуструпа по  C++ (если есть такое, конечно ).

Отправлено: 01:08, 01-02-2003 | #7


Модер


Сообщения: 1716
Благодарности: 17

Профиль | Сайт | Отправить PM | Цитировать


Guest
1) вопрос не ко мне.

2) До известного уровня системных знаний в Windows - достаточно книг Рихтера. C++ и MFC никакого отношения к Windows не имеют.

-------
Васкецов Сергей
http://registry.oszone.net


Отправлено: 20:58, 01-02-2003 | #8


Аватара для Guest

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



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Что такое текущая директория?

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
что за папка (директория) $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




 
Переход