Я долго уже сижу над этой проблемой, многое пробовал и думал, что обойдусь своими силами, и не придётся просить о помощи, но я больше не могу, я потратил уже несколько недель…
Помогите справиться с проблемой, если это вообще возможно.
Проблема заключается в том, что
некий глобальный хук не снимается ни через UnhookWindowsHookEx, ни при завершение основного процесса с выгрузкой dll,
с некоторых процессов, а именно с «Windows Command Processor», то есть с процесса стандартного cmd.exe. Но не просто процесса cmd.exe, а
только если это был запущен батник, который запускал другой процесс (в моём случае запускался на исполнение и успешно завершался Ruby-скрипт) и этот батник не закрывается в конце работы, а ждёт команды, или висит на pause. И ещё важным моментом есть то, что это происходит только, если такой батник запустить
после запуска программы с установкой глобального хука. То есть если батник уже был запущен и стоял на ожидании, когда устанавливается глобальный хук, то хук к этому батнику не цепляется вообще. Напрашивается вывод, что сыграл роль тот процесс, которых был запущен батником, отработал и выгрузился.
За хуком я слежу через Unlocker (открываю ним dll-файл). Вот как это выглядит:
Во время работы:
После завершения процесса и снятия хуков:

Осталось 3 батника :(
Через TaskInfo видно, что у каждого присутствует моя dll в списке прикреплённых модулей. И эти процессы сами никак не освобождаются от dll.
Мой dll-файл при этом не доступен для файловых операций, а мне его как раз надо перемещать в процессе обновления после завершения процесса, почему я парюсь с этой проблемой уже столько времени.
Помогает только закрытие каждого батника, или разблокировка через Unlocker.
Я в тупике :(
Я имею дело с 3 разными хуками: WH_KEYBOARD, WH_MOUSE, WH_CALLWNDPROC и WH_CBT
Что я уже пробовал:
1) Сначала хуки ставились и освобождались только в dll, а с exe только вызывал нужные функции setHook/clearHook.
Результаты: WH_KEYBOARD, WH_MOUSE — снимаются легко и без проблем, WH_CALLWNDPROC — залипает когда приложение прибить из TaskManager. Со временем потом некоторые приложения сами освобождаются (через несколько секунд/минут), а некоторые, которые работают на низком уровне, типа программ управляющих тачпадом или глобальными гарячими клавишами, не хотят освобождаться сами, даже после длительного ожидания. WH_CBT тогда ещё не пробовал.
2) Ища решение проблемы, прочитал здесь в нити
«Постановка и снятие хуков из DLL»Автор: Spider84
Дата: 20.08.03
:
> Что будет если снять задачу с приложения, которое поставило хук? Хук останеться в системе?
>> Практика показывает, что как только завершается нить, вызывавшая SetWindowsHookEx, так dll с хуком и выгружается.
У меня же SetWindowsHookEx находится в dll. Возникла мысль, что нужно перенести установку хука в exe, так как именно он точно выгружается, и всё будет ок.
Но когда я так всё сделал (помогло обсуждение в
этой нитиАвтор: fromrus
Дата: 16.09.08
), то получилось так: WH_KEYBOARD, WH_MOUSE — снимаются легко и без проблем, WH_CALLWNDPROC и WH_CBT — тоже снимаются даже при ручном завершении процесса, но
не снимаются с описанного cmd процесса, даже при нормальном завершении процесса, который их ставил.
3) Потом я уже пробовал извращаться и запускал таймер внутри каждого хукнутого процесса, и в нём следил, запущен ли основной процесс, и если нет — вызывал UnhookWindowsHookEx. Оказалось, что, действительно, такие таймеры работают, даже когда основной процесс прибить. И это сработало даже в комбинации с вариантом 1): хуки, те, что залипали при ручном завершении процесса, таким таймером освобождались (я даже лог из этого таймера вёл и следил за каждым из процессов). Но это не помогло для cmd…
таймер даже не функционировал под таким процессом.
У меня всё…
Я не понимаю, чем эта ситуация с cmd такая уникальная, что возникает такой аффект, но я с этим справиться не могу :(
Есть ещё мысли, о debug-хуках, так как о них пишет, что ними можно делать что-то с другими хуками, но мне нужен хоть лучик надежды, чтобы продолжить попытки…
Помогите пожалуйста, побороть эту проблему, если это возможно.
Нужно хоть каким-то способом убрать WH_CBT/WH_CALLWNDPROC хуки из подобных cmd-процессов при завершении программы. Метод может быть самый фантастический, лишь бы работал и не был ощутим по производительности (даже те таймеры, которые я пробовал не были заметны в системе).
Код приводить не вижу смысла, так как всё работает и я много раз сверялся и следовал примерам из разных нитей этого форума. Тут дело в чём-то непонятном…
Очень надеюсь на вашу помощь.
С уважением, Юрий.