Сейчас на форуме: jinoweb (+4 невидимых) |
eXeL@B —› Программирование —› Получени пути |
Посл.ответ | Сообщение |
|
Создано: 04 апреля 2020 22:41 · Поправил: AntiE · Личное сообщение · #1 Здравствуйте. Суть проблемы - при перетаскивании файла на окно программы нужно получить полный путь к файлу, казалось бы тривиальная задача, но на системах < десятки если путь длиннее MAX_PATH, IDataObject::GetData с CF_HDROP не отрабатывает. Тут нужен какой-то финт, скорее всего путь "ломается" еще где-то на уровне ОС, до попадания объекта в приложение. Поскольку у многих стоит свежая ОС и заморачиваться с тестами на виртуалках с Вин7 вам будет лень, на 10-ке можно воспроизвести немного иной вектор того же кейса - создать файл с "кривым" именем и тащить его, например: echo.>"\\?\X:\ badname.txt " На васме никто пока решения не нашел, решил попытать удачу здесь, надеясь на иной уровень знания ОС у местных спецов. |
|
Создано: 04 апреля 2020 22:57 · Личное сообщение · #2 |
|
Создано: 04 апреля 2020 23:02 · Личное сообщение · #3 rmn пишет: Полное имя файла ни на одной винде не может быть больше MAX_PATH Ну я бы |
|
Создано: 04 апреля 2020 23:05 · Личное сообщение · #4 |
|
Создано: 04 апреля 2020 23:11 · Личное сообщение · #5 rmn In the ANSI version of this function, the name is limited to MAX_PATH characters. To extend this limit to 32,767 wide characters, call the Unicode version of the function (GetFullPathNameW), and prepend "\?" to the path. For more information, see Naming a File. У него специфическая проблема с драгидропом. ----- старый пень |
|
Создано: 04 апреля 2020 23:19 · Поправил: AntiE · Личное сообщение · #6 Безусловно в описываемой ситуации в качестве IDropSource будет выступать любой файловый менеджер умеющий работать с длинными путями (штатный виндовый эксплорер их не умеет). Чтобы использовать их из кода на WinXP - Win8 достаточно в начало пути добавить префикс "\\?\" и писать на чистом WinAPI без програмных оберток вашего ЯП. В хидерах сдк часто встречается конструкция WCHAR cFileName[ MAX_PATH ], возможно и OLE спотыкается на этом. Вот тут-то и нужно придумать способ поймать полный путь при перетаскивании. |
|
Создано: 04 апреля 2020 23:20 · Личное сообщение · #7 |
|
Создано: 04 апреля 2020 23:33 · Поправил: AntiE · Личное сообщение · #8 r_e пишет: А ты уверен что там CF_HDROP для такого случая кидается? Ну я естественно предварительно проверяю формат через QueryGetData и только потом пытаюсь получить данные, так что да, уверен. Вот вывод всех доступных форматов при перетаскивании файла из длинного пути: Code:
r_e пишет: попробуй найти что там в HGLOBAL -> STGMEDIUM STGMEDIUM заполняется вызовом IDataObject::GetData который собственно и фэйлится. P.S. Если вы тестируете на Win10 с файлом созданным командной строкой из первого поста, форматы будут точно такими же, однако из-за специфики имени файл будет восприниматься как директория и если это смущает, можно заменить невалидный символ с пробела на что-то еще итп. Хотя суть остается, в данном случае путь просто будет обрезаться и задача получить его целиком, в остальном все идентично. |
|
Создано: 05 апреля 2020 10:16 · Личное сообщение · #9 |
|
Создано: 05 апреля 2020 21:09 · Поправил: VOLKOFF · Личное сообщение · #10 r_e пишет: чтобы понять где фейлится и что там вообще есть Code:
В MSDN 'E_INVALIDARG' - The dwDirection value is not valid Цепочка вызовов выглядит приблизительно так: Code:
Хотя по логике вещей нужно сначала посмотреть источник на предмет формирования корректного IDataObject и проблема может быть там. | Сообщение посчитали полезным: AntiE |
|
Создано: 05 апреля 2020 23:03 · Поправил: AntiE · Личное сообщение · #11 Действительно, насколько мне удалось отследить, OLE прерывает формирование пути в файловом менеджере по достижению MAX_PATH при начале перетаскивания файла и соответственно объект получается целевым окном уже не валидным. Механизм стал более понятен, однако вопрос остается, есть ли способ "перехватить" весь этот процесс для получения полного пути, или задача не решаемая? |
|
Создано: 06 апреля 2020 09:54 · Личное сообщение · #12 |
|
Создано: 06 апреля 2020 11:02 · Поправил: _MBK_ · Личное сообщение · #13 Ну человек же на хакерский форум вопрос задал, возможно, он хочет некий подпольный способ в обход OLE влезть в память процесса и прочухать какой именно файл был последний раз схвачен мышкой Смех смехом, но сейчас глянул последовательность действий, которую проделывает эксплорер с файловой системой и реестром при каждом выборе нового файла - это можно отследить снаружи безо всякого влезания в процесс. Пока что данный способ единственный номинант на самое извращенное решение |
|
Создано: 06 апреля 2020 17:10 · Личное сообщение · #14 |
eXeL@B —› Программирование —› Получени пути |