Текущий каталог Win32, блокировка и интеграция с оболочкой

В Win32 текущий рабочий каталог вашего основного потока устанавливается в место, из которого был запущен исполняемый файл. Моя проблема заключается в том, что даже после вызова SetCurrentDirectory() в другом месте процесс, по-видимому, все еще имеет объект файловой системы, ссылающийся на этот начальный каталог запуска (поддающийся проверке с помощью такого инструмента, как Process Explorer), что означает этот директор не может быть удален процессом.

Кто-нибудь здесь знает не слишком хакерское решение? Я специально сталкиваюсь с проблемой с программой, которая интегрируется с проводником (добавление глагола в раздел реестра HKCR\Directory\shell), мне нужно обработать файлы в каталоге, щелкнутом правой кнопкой мыши, и удалить исходный каталог, что невозможно потому что исходный рабочий каталог установлен, как вы уже догадались, в каталоге, по которому щелкнули правой кнопкой мыши.

EDIT: я выберу подход "использовать вспомогательный запуск из нормального каталога". Это может быть не очень элегантно, но оно будет работать и не требует никаких неприятных хаков.


person snemarch    schedule 17.03.2009    source источник
comment
Вы уверены, что процесс содержит ссылку не на себя, а на каталог?   -  person Sedat Kapanoglu    schedule 17.03.2009
comment
Да, чтобы быть уверенным, я сделал простую программу, которая ничего не делает, кроме SetCurrentDirectory(), за которой следует MessageBox(), который удерживает каталог заблокированным :(   -  person snemarch    schedule 17.03.2009
comment
retag: добавлен win32, удален текущий. current бесполезен в качестве тега.   -  person George    schedule 17.03.2009
comment
Почему вы пытаетесь удалить каталог, из которого был запущен исполняемый файл? Если это удастся, разве это не удалит программу, которую вы запускаете?   -  person Adam Rosenfield    schedule 17.03.2009
comment
Адам, каталог, из которого запущен != каталог, содержащий исполняемый файл. Пример из оболочки: cd c:\temp, c:\windows\system32\calc.exe - calc.exe cwd - это c:\temp, а не c:\windows\system32   -  person snemarch    schedule 17.03.2009


Ответы (1)


Самым простым решением может быть просто создать небольшой вспомогательный процесс, который запускается в любом указанном вами каталоге (например, c:\), а затем просто выйти и позволить ему делать свое дело. Возможно, его нужно синхронизировать с мьютексом или, возможно, просто повторить попытку два или три раза по таймеру...

У меня была другая мысль: вы можете использовать CreateFile() с FILE_FLAG_DELETE_ON_CLOSE. Затем он должен исчезнуть, когда все его отпустят, но только если он был открыт с помощью FILE_SHARE_DELETE.

person i_am_jorf    schedule 17.03.2009
comment
Это сработает, но кажется немного неуклюжим - хотя может быть самым простым решением. - person snemarch; 17.03.2009
comment
удалить при закрытии - интересная идея, но CreateFile не работает с каталогами (если только вы не используете FILE_FLAG_BACKUP_SEMANTICS, но я не уверен, что это сработает, и для этого требуются привилегии SE_BACKUP_NAME) :) - person snemarch; 17.03.2009
comment
Возможно ... Я только бегло изучил документы, когда вспомнил об удалении при закрытии ... - person i_am_jorf; 17.03.2009