Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Visual C++/MFC/WTL > Доступ к директории исполняемого файла |
Автор: xTr1m 18.1.2013, 12:53 | ||||
Доброго времени суток. В корпоративном коде (назовем это так) директория, в которой находится запущенная программа определяется так
но разбираясь с Win32, прочитал, что путь также всегда передается в командной строке первым параметром, также нашел, что в студии есть переменные, которые позволяют получить путь вот так:
Выглядит проще, работает быстрее. Есть только вопрос, а можно полагаться на переменные __argc и __targv и всегда ли путь будет находиться первым параметром в командной строке? А может есть другие варианты? Заранее спасибо. |
Автор: Albor 18.1.2013, 15:22 | ||
Можно так ещё
|
Автор: Albor 19.1.2013, 22:07 | ||
Слэш должен быть обязательно - получим путь без имени файла. В чём может быть проблема (если не считать случай запуска, когда командной строки может не быть)? |
Автор: volatile 19.1.2013, 23:18 | ||||
Albor, GetCommandLine возвращает всю коммандную строку целиком. например, при
Ваш способ вернет:
Это, не совсем |
Автор: Albor 20.1.2013, 10:57 |
Это понял, но программист наверняка знает как запускается его программа и может парсить строку как ему угодно. Кстати, озвученная вами _pgmptr в MFC-проекте имеет значение NULL, соответственно вызов _get_pgmptr() заканчивается аварией. |
Автор: Albor 20.1.2013, 11:54 | ||
MAX_PATH подошло бы больше, да и вызов GetModuleHandle(NULL) явно лишний, т.к. в GetModuleFileName() первым параметром можно передать NULL и получить тот же эффект. |
Автор: volatile 20.1.2013, 19:37 |
Albor, в MFC все прекрасно работает. Озвучил я для того чтобы обратились к мсдн. там и плюсы и минусы. (поищите на форуме про юникодный/неюникодный проекты, это грабли для новичков обсуждались тыщу раз, надоело уже.) |
Автор: Albor 20.1.2013, 20:11 | ||
Да, работает, извиняюсь, мне нужно было обращаться к _wpgmptr. |
Автор: xTr1m 21.1.2013, 14:18 | ||||
Спасибо большое. Получается, что буду писать так, как есть сейчас. Этот код не подходит, так как первым параметром не всегда идет
а этот, так как если будет два параметра, то нужен чуть более сложный разбор
|
Автор: volatile 21.1.2013, 17:48 |
xTr1m, да не нужен будет с _get_pgmptr() разбор. (это я про совсем другое говорил.) Просто у меня есть сильноее подозрение, что он работает точно также, извлекая из arg[0]; но вопрос сей подробно не изучал, так как Используйте ваш первый вариант. Имхо нормальный! Единственно, теоретически, путь может быть длиной до 32К. И в этом случае и 2048 и тем более MAX_PATH обломаюцца. Добавлено через 11 минут и 36 секунд Кстати, на сверх длинных путях, обламываюцца многие программы, если вас это утешит. ![]() ну или делайте с расчетом на 32К. |
Автор: Albor 22.1.2013, 08:10 |
Можно (если очень осторожно) использовать http://msdn.microsoft.com/ru-ru/library/windows/desktop/aa364934.aspx (внимательно читаем ремарку). А это по http://msdn.microsoft.com/ru-ru/library/vstudio/930f87yf(v=vs.100).aspx, можно найти ещё кучу статей по решению проблем длинного пути. Но, надеюсь, что у xTr1m данной проблемы нет. |
Автор: volatile 22.1.2013, 09:47 |
![]() вообще не из той оперы |
Автор: Albor 22.1.2013, 12:01 |
volatile, если, допустим, что моя программа не многопоточная и я ни где не устанавливаю текущую директорию,то почему http://www.radikal.ru |
Автор: Albor 3.2.2013, 09:17 | ||
Решил всё же окончательно разобраться с данным вопросом. Итак, что мы имеем при запуске нашей программы? Я решил посмотреть в сторону CreateProcess(): в неё передаётся (из того что нас интересует) 1. имя приложения и командная строка - данные параметры используются довольно хотрО, то есть мы можем и не передавать полный путь к исполняемому файлу - система сама будет искать файл по определённому алгоритму и, если найдёт, то запустит. Из этого следует то, что уже обсуждалось - через командную строку можно и не получить требуемое. 2. текущая директория - может передаваться, а может и нет, смотря кто и как запускает процесс, то есть, вызовом GetCurrentDirectory() мы можем получить текущую директорию родительского процесса либо явно указываемую при создании процесса, либо установленную вызовом SetCurrentDirectory() - опять-таки мы не получаем ни какой гарантии что текущая директория то что нам нужно. Выходит, что входные параметры не дают 100 процентной информации для решения задачи, но... создатель процесса что-то ещё и делает - внутри функции путь к исполняемому файлу известен (если файл найден конечно), вот здесь, по моему предположению, и присваивается значение переменной _pgmptr, либо её UNICODE - версии _wpgmptr, которая позиционируется как полный путь и имя исполняемого файла. Теперь заглянем в русскую редакцию 2009г книги Рихтера "WINDIWS via c/c++", и посмотрим его мнение на счёт этой и некоторых других глобальных переменных
Соответствующей функцией, по указанию этого же источника, является GetModuleFileName(). Выходит, что данная функция гарантированно даст нам правильный результат. Остался вопрос с MAX_PATH. MSDN прямо указывает, что путь не должен превышать данного значения, но тут же делается оговорка для NTFS. Рихтер тоже однозначно не высказывается по этому вопросу - он говорит примерно то же самое и делает замечание, что размер, определённый в MAX_PATH можно обойти, вот только для чего и кому это нужно, для читателя остаётся загадкой. Для себя я сделал такой вывод, что если не хочешь проблем, то не нужно именовать файлы и каталоги своей программы так, чтобы они превышали MAX_PATH, а пользователю не следует пихать программу туда, от куда её будет тяжело достать (кстати, в некоторых статьях по решению проблемы длинных путей, Microsoft предлагает переименовать файлы и каталоги более короткими именами). |
Автор: HANDLE 9.4.2013, 14:39 | ||
Все можно сократить до безобразия, и сверхдлинные пути не помеха (32768 - предел), а MAX_PATH можно преодолеть путем перетаскивания файлов из папки в папку в пределах одного диска.
|