Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Хук в отдельном потоке службы


Автор: Leonid1611 22.9.2008, 14:08
Здравствуйте.
Есть класс для работы с хуком (учитывает пользовательскую активность). Из под консольного приложения все запускается и работает.
Хочу делать это из службы для чего в службе создается отдельный поток в котором хук и устанавливается.
Служба запускается нормально но при завершении вываливается ошибка (в Win32Exception) - "Неверный дескриптор обработчика" при вызове UnhookWindowsEx. 
Метод установки хука:
Код

        private void Start(bool InstallMouseHook, bool InstallKeyboardHook)
        {
            startTime = DateTime.Now;

            // хук мыши 
            if (InstallMouseHook && hMouseHook == IntPtr.Zero)
            {
                //создаем процедуру 
                MouseHookProcedure = new HookProc(MouseHookProc);
                hMouseHook = SetWindowsHookEx(
                    WH_MOUSE_LL,
                    MouseHookProcedure,
                    Marshal.GetHINSTANCE(this.GetType().Module),
                    //Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),
                    0);
                //получаем дескриптор
                if (hMouseHook == IntPtr.Zero)
                {
                    int error = Marshal.GetLastWin32Error();
                    Stop(true, false, false);
                    throw new Win32Exception(error);
                }
            }
            // хук клавиатуры
            if (InstallKeyboardHook && hKeyBoardHook == IntPtr.Zero)
            {
                KeyboardHookProcedure = new HookProc(KeyboardHookProc);
                hKeyBoardHook = SetWindowsHookEx(
                        WH_KEYBOARD_LL,
                        KeyboardHookProcedure,
                        Marshal.GetHINSTANCE(this.GetType().Module),
                        //Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),
                        0);

                if (hKeyBoardHook  == IntPtr.Zero)
                {
                    int error = Marshal.GetLastWin32Error();
                    Stop(false, true, false);
                    throw new Win32Exception(error);
                }
            }
            // Устанавливаем таймер 
            timer = new System.Timers.Timer(delay);
            timer.AutoReset = false;            
            timer.Start();            
        }

Метод удаления хука:
Код

 private void Stop(bool UnInstallMouseHook, bool UnInstallKeyboardHook, bool ThrowExceptions)
        {
            if (hMouseHook != IntPtr.Zero && UnInstallMouseHook)
            {
                // расхучить 
                bool retMouse = UnhookWindowsHookEx(hMouseHook);
                hMouseHook = IntPtr.Zero;
                if (!retMouse && ThrowExceptions)
                {
                    int error = Marshal.GetLastWin32Error();
                    throw new Win32Exception(error);
                }
            }
            if (hKeyBoardHook != IntPtr.Zero && UnInstallKeyboardHook)
            {
                bool retKeyBoard = UnhookWindowsHookEx(hKeyBoardHook);
                hKeyBoardHook = IntPtr.Zero;
                if (!retKeyBoard && ThrowExceptions)
                {
                    int error = Marshal.GetLastWin32Error();
                    throw new Win32Exception(error);
                }
            }
        }

Методы OnStart и OnStop сервиса :
Код

        protected override void OnStart(string[] args)
        {
           
            log = new StreamWriter(new FileStream("log.txt",FileMode.Append));            
            logger = new Logger(log);
            ts = new Thread(new ThreadStart(logger.Start));
            ts.Start();

        }

        protected override void OnStop()
        {
            // TODO: Add code here to perform any tear-down necessary to stop your service.            
            logger.Stop();            
            ts.Abort();
        }


Подскажите пожалуйста почему неверный дескриптор.

Автор: Leonid1611 23.9.2008, 13:34
Разобрался с проблемой. Необходимо было:
1) Запустить в потоке цикл обработки сообщений (message loop) - System.Windows.Forms.Application.Run()
2) Разрешить сервису взаимодействие с рабочим столом - Службы - Свойства - Вход в систему - Разрешить взаимодействие с рабочим столом.

Автор: Ronin08 24.9.2008, 11:33
Спасибо. Очень пригодились в качестве пимера твои исходники!

Автор: SoulJr 10.6.2011, 14:11
Не могли бы кто нибудь првести полный исходник данного примера...необходимо такая же служба для сдачи курсовой

Автор: SoulJr 10.6.2011, 16:36
 logger = new Logger(log);
я не понял откуда взялся этот логер?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)