![]() |
|
![]() ![]() ![]() |
|
xTr1m |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 692 Регистрация: 9.2.2005 Где: Москва Репутация: нет Всего: 1 |
Доброго времени суток. В корпоративном коде (назовем это так) директория, в которой находится запущенная программа определяется так
но разбираясь с Win32, прочитал, что путь также всегда передается в командной строке первым параметром, также нашел, что в студии есть переменные, которые позволяют получить путь вот так:
Выглядит проще, работает быстрее. Есть только вопрос, а можно полагаться на переменные __argc и __targv и всегда ли путь будет находиться первым параметром в командной строке? А может есть другие варианты? Заранее спасибо. |
||||
|
|||||
Albor |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 589 Регистрация: 28.2.2009 Репутация: 7 Всего: 9 |
Можно так ещё
|
|||
|
||||
volatile |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 4 Всего: 85 |
Нет, не всегда. Если программа запущена например, из другой програаммы с помощью CreateProcess(), то там может быть вообще нулевая строка. Есть и еще случаи. Кроме того там может находицца относительный путь.
а так вобще делать нельзя. Надеятесь, что в дополнительных параметров накогда не встретицца '\\' ? Кроме того, все что выше, относицца и к этому варианту. В студии есть уже готовая переменная с путем программы _pgmptr, и функция _get_pgmptr(); Ими особо не пользовался, поэтому сказать за них ничо не могу.
Есть золотое правило - "если код работает, не трогай его". ![]() Еще есть - "premature optimization.." и все такое Единственное, что мне здесь не очень нравицца это захардкоденное 2048 Это сообщение отредактировал(а) volatile - 19.1.2013, 01:21 |
||||||
|
|||||||
Albor |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 589 Регистрация: 28.2.2009 Репутация: 7 Всего: 9 |
Слэш должен быть обязательно - получим путь без имени файла. В чём может быть проблема (если не считать случай запуска, когда командной строки может не быть)? |
|||
|
||||
volatile |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 4 Всего: 85 |
Albor, GetCommandLine возвращает всю коммандную строку целиком. например, при
Ваш способ вернет:
Это, не совсем Это сообщение отредактировал(а) volatile - 19.1.2013, 23:24 |
||||
|
|||||
Albor |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 589 Регистрация: 28.2.2009 Репутация: 7 Всего: 9 |
Это понял, но программист наверняка знает как запускается его программа и может парсить строку как ему угодно. Кстати, озвученная вами _pgmptr в MFC-проекте имеет значение NULL, соответственно вызов _get_pgmptr() заканчивается аварией.
Это сообщение отредактировал(а) Albor - 20.1.2013, 11:48 |
|||
|
||||
Albor |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 589 Регистрация: 28.2.2009 Репутация: 7 Всего: 9 |
||||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 4 Всего: 85 |
Albor, в MFC все прекрасно работает. Озвучил я для того чтобы обратились к мсдн. там и плюсы и минусы. (поищите на форуме про юникодный/неюникодный проекты, это грабли для новичков обсуждались тыщу раз, надоело уже.) |
|||
|
||||
Albor |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 589 Регистрация: 28.2.2009 Репутация: 7 Всего: 9 |
Да, работает, извиняюсь, мне нужно было обращаться к _wpgmptr. |
|||
|
||||
xTr1m |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 692 Регистрация: 9.2.2005 Где: Москва Репутация: нет Всего: 1 |
Спасибо большое. Получается, что буду писать так, как есть сейчас. Этот код не подходит, так как первым параметром не всегда идет
а этот, так как если будет два параметра, то нужен чуть более сложный разбор
|
||||
|
|||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 4 Всего: 85 |
xTr1m, да не нужен будет с _get_pgmptr() разбор. (это я про совсем другое говорил.) Просто у меня есть сильноее подозрение, что он работает точно также, извлекая из arg[0]; но вопрос сей подробно не изучал, так как Используйте ваш первый вариант. Имхо нормальный! Единственно, теоретически, путь может быть длиной до 32К. И в этом случае и 2048 и тем более MAX_PATH обломаюцца. Добавлено через 11 минут и 36 секунд Кстати, на сверх длинных путях, обламываюцца многие программы, если вас это утешит. ![]() ну или делайте с расчетом на 32К. |
|||
|
||||
Albor |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 589 Регистрация: 28.2.2009 Репутация: 7 Всего: 9 |
Можно (если очень осторожно) использовать GetCurrentDirectory() (внимательно читаем ремарку).
А это по максимальным путям, можно найти ещё кучу статей по решению проблем длинного пути. Но, надеюсь, что у xTr1m данной проблемы нет. |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 4 Всего: 85 |
||||
|
||||
Albor |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 589 Регистрация: 28.2.2009 Репутация: 7 Всего: 9 |
||||
|
||||
Albor |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 589 Регистрация: 28.2.2009 Репутация: 7 Всего: 9 |
Решил всё же окончательно разобраться с данным вопросом. Итак, что мы имеем при запуске нашей программы? Я решил посмотреть в сторону CreateProcess(): в неё передаётся (из того что нас интересует)
1. имя приложения и командная строка - данные параметры используются довольно хотрО, то есть мы можем и не передавать полный путь к исполняемому файлу - система сама будет искать файл по определённому алгоритму и, если найдёт, то запустит. Из этого следует то, что уже обсуждалось - через командную строку можно и не получить требуемое. 2. текущая директория - может передаваться, а может и нет, смотря кто и как запускает процесс, то есть, вызовом GetCurrentDirectory() мы можем получить текущую директорию родительского процесса либо явно указываемую при создании процесса, либо установленную вызовом SetCurrentDirectory() - опять-таки мы не получаем ни какой гарантии что текущая директория то что нам нужно. Выходит, что входные параметры не дают 100 процентной информации для решения задачи, но... создатель процесса что-то ещё и делает - внутри функции путь к исполняемому файлу известен (если файл найден конечно), вот здесь, по моему предположению, и присваивается значение переменной _pgmptr, либо её UNICODE - версии _wpgmptr, которая позиционируется как полный путь и имя исполняемого файла. Теперь заглянем в русскую редакцию 2009г книги Рихтера "WINDIWS via c/c++", и посмотрим его мнение на счёт этой и некоторых других глобальных переменных
Соответствующей функцией, по указанию этого же источника, является GetModuleFileName(). Выходит, что данная функция гарантированно даст нам правильный результат. Остался вопрос с MAX_PATH. MSDN прямо указывает, что путь не должен превышать данного значения, но тут же делается оговорка для NTFS. Рихтер тоже однозначно не высказывается по этому вопросу - он говорит примерно то же самое и делает замечание, что размер, определённый в MAX_PATH можно обойти, вот только для чего и кому это нужно, для читателя остаётся загадкой. Для себя я сделал такой вывод, что если не хочешь проблем, то не нужно именовать файлы и каталоги своей программы так, чтобы они превышали MAX_PATH, а пользователю не следует пихать программу туда, от куда её будет тяжело достать (кстати, в некоторых статьях по решению проблемы длинных путей, Microsoft предлагает переименовать файлы и каталоги более короткими именами). Это сообщение отредактировал(а) Albor - 3.2.2013, 09:31 |
|||
|
||||
HANDLE |
|
|||
Новичок Профиль Группа: Участник Сообщений: 5 Регистрация: 25.6.2008 Репутация: нет Всего: нет |
Все можно сократить до безобразия, и сверхдлинные пути не помеха (32768 - предел), а MAX_PATH можно преодолеть путем перетаскивания файлов из папки в папку в пределах одного диска.
|
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |