GetOpenFileName оставляет открытой директорию

Тема в разделе "WASM.WIN32", создана пользователем gorodon, 21 окт 2010.

  1. gorodon

    gorodon New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2009
    Сообщения:
    301
    Система XP SP2.
    В программе вызывается GetOpenFileName, после указания юзером нужного файла (например C:\temp\1.txt) функция возвращает TRUE и полный путь выбранного файла по адресу OPENFILENAME.lpstrFile - все как положено... НО
    при этом появляется открытый ресурс - директория файла (в моем примере C:\temp)...
    Собственно, вопрос возник, когда понадобилось удалить директорию (в моем примере C:\temp) после вызова GetOpenFileName и манипуляций с файлом ...
    Почитал MSDN, но ничего путного не нашел... Если кто сталкивался - порекомендуйте решение, желательно на уровне Windows API... совсем не хочется искать открытый хэндл через NtQuerySystemInformation.
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    gorodon
    Не нужно ничего освобождать, что вы не открывали. Наверно описатель освободится при следующем вызове/выгрузке модуля. Более того при первом вызове этой апи очень много чего подгружается и открывается.
     
  3. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    Почитай описание функции для удаления папок. Если я не ошибаюсь, она не удаляет папки, в которых есть файлы или папки. Сначала удали все содержимое твоей папки темп, а потом только и саму папку
     
  4. gorodon

    gorodon New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2009
    Сообщения:
    301
    MSoft
    Естественно, так и делаю... Для обнаружения открытых описателей использовал OpenedFilesView - вот она мне и показывает, что после вызова GetOpenFileName описатель папки остается открытым (с атрибутами: Доступ на чтение,
    FILE_SHARE_READ|FILE_SHARE_WRITE).

    Clerk
    Да, при следующем вызове GetOpenFileName (C:\temp1\1.txt) остается открытой директория C:\temp1...
    Но тогда это баг...
    Приведу еще пример - я вызвал в програме GetOpenFileName, а юзер указал файл, находящийся на флешке...
    После этого указанный файл был переписан во временный каталог программы - и я считаю, что программа никакого
    отношения к флешке(к диску, указонному юзером) уже не имеет.... так НЕТ же - ИМЕЕТ!, т.к. остался открытым
    описатель директории на флешке (в GetOpenFileName). А отсюда вытекают еще более серьезные последствия - юзер
    дергает флешку при работающей программе - программа виснет....
     
  5. 100gold

    100gold New Member

    Публикаций:
    0
    Регистрация:
    26 фев 2010
    Сообщения:
    165
    Можешь попробовать перечислить все свои хендлы и закрыть нужный. Только я хз как система отреагирует на такой оборот событий. Но можно попробовать )
     
  6. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    код в студию
     
  7. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    MSoft
    Вот простейший пример где открытый файл закрывается сразу после прочтения в память, а директорию в которой он сидит можно удалить только после закрытия месаджбокса.

    gorodon
    Имхо для серьёзных программ не стоит юзать эту студенческую поделку от M$, а лучше написать свой диалог для работы с файлами ;)
     
  8. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Извращенцы.
    gorodon
    SetCurrentDirectory на заведомо существующую папку, не лежащую внутри удаляемой. Функции WinAPI держат открытым хэндл текущей папки, а GetOpenFileName делает папку, из которой выбран файл, текущей.
     
  9. gorodon

    gorodon New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2009
    Сообщения:
    301
    diamond
    А-а, так GetOpenFileName текущую дерикторию изменяет... Спасибо! я сразу и не догнал... :dntknw:
    (Решение - при вызове GetCurrentDirectory-GetOpenFileName-SetCurrentDirectory - все нормально)
    Спасибо diamond, Y_Mur и остальным участникам.
    Тему можно закрыть.
     
  10. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    gorodon
    Это никакая не утечка ресурсов. Вобще с чего вы взяли что нужно мониторить и освобождать какието обьекты ?
    После первого вызова GetOpenFileName() подгружается большое число модулей, выделяется много памяти, создаётся большое число обьектов(несколько десятков). Так что за бредовые идеи вам пришли на ум освобождать самостоятельно все ресурсы =)
     
  11. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Этот диалог огромный костыль. Если не устраивает сделайте свою реализацию, желательно ядерную.
     
  12. gorodon

    gorodon New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2009
    Сообщения:
    301
    Clerk
    Да, вы правы - утечки ресурсов нет, просто я сразу не понял, что GetOpenFileName меняет ресурс "текущая дериктория" - отсюда и бредовые идеи...
    Отсутсвие в документации такого важного момента (смена текущей директории - последствия описаны в #1, #4) -
    ... у меня в программе несколько лет ездил :dntknw:
    Связка GetOpenFileName-SetCurrentDirectory(нужная директория) пока вполне устраивает...может и напишу свою реализацию когда-нить... :)
     
  13. KIV

    KIV Member

    Публикаций:
    0
    Регистрация:
    16 июл 2009
    Сообщения:
    231
    Можно у GetOpenFileName указать флаг NOCHANGEDIR. И тогда он не будет менять текущий каталог и соответственно не будет его занимать.
     
  14. gorodon

    gorodon New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2009
    Сообщения:
    301
    KIV
    MSDN:

    OFN_NOCHANGEDIR
    Restores the current directory to its original value if the user changed the directory while searching for files.
    Windows NT 4.0/2000/XP: This flag is ineffective for GetOpenFileName.
     
  15. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    gorodon
    Под XP SP2 очень даже effective. В "древних" мсдн времен w2k тоже никаких подобных приписок не было. Поэтому либо это "враки", либо "нововведения" для висты\семерки.