Lucian
Lucian

Reputation: 894

Hook to window events from a c# windows service application does not work

I am trying to develop an application that will hook to windows events and notify me when for eg. the active window has changed. I am using Win7 64 with .net 4.0 VS 2010
To do this I made a Window Service type of project, created a service installer in it, and OnStart method from the template service project I registered to events using SetWinEventHook from user32.dll. Everything seems fine except the fact that I am not receiving anything in the callback method passed to SetWinEventHook. My code looks like this:

protected override void OnStart(string[] args)
{
    workerThread = new Thread(OnTimer);
    workerThread.Start();
}

public void OnTimer()
{
       UserWatchdog userWatchdog = new UserWatchdog();
        UserWatchdog.SubscribeToWindowEvents();
        ScreenTime.EventLoop.Run();
}
public static WinEventProc _winEventProc = new WinEventProc(WindowEventCallback);
public static void SubscribeToWindowEvents()
    {
        if (windowEventHook == IntPtr.Zero)
        {
            windowEventHook = SetWinEventHook(
            0x00000001,
            0x7FFFFFFF,
            IntPtr.Zero,             // hmodWinEventProc
            _winEventProc,
            0,                       // idProcess
            0,                       // idThread
            WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
         }
    }
    private static void WindowEventCallback(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
    {
        //I NEVER GET HERE
        ScreenTime.WatchdogAnalyzer.analyze(hwnd);
    }

     public static void Run()
    {

        MSG msg;
        while (!_shouldStop)
        {
            WatchdogAnalyzer.printActiveWindow();
            if (PeekMessage(out msg, IntPtr.Zero, 0, 0, PM_REMOVE))
            {
                if (msg.Message == WM_QUIT)
                    break;
                TranslateMessage(ref msg);
                DispatchMessage(ref msg);
            }
        }
    }

Do you have any idea why I get no events from Win? Thank you

Upvotes: 1

Views: 1854

Answers (2)

Reg Edit
Reg Edit

Reputation: 6914

What @DavidCrowell said, plus you may possibly be able to make use of this property for the service (never tried):

enter image description here

Per this MS page,

In most cases, it is recommended that you not change the Allow service to interact with desktop setting. If you allow the service to interact with the desktop, any information that the service displays on the desktop will also be displayed on an interactive user's desktop. A malicious user could then take control of the service or attack it from the interactive desktop.

Since this implies an interaction between windows on the two desktops, you may be able to use your hook if you set this property on the service.

Upvotes: 1

David Crowell
David Crowell

Reputation: 3813

A service runs on a different Window Station (Desktop) than user applications. Even without services, there can be several Window Stations (RDP, UAC, etc).

You'll need to run a process on the user's local Desktop and use it to catch the events. It can then communicate with the service.

Upvotes: 3

Related Questions