Processing Windows Messages

Hi, how can I caputure Windows Messages in a Service Application?? i.e., get my service application to responde to WM messages..

Comments

  • [b][red]This message was edited by stober at 2003-8-6 8:48:1[/red][/b][hr]
    : Hi, how can I caputure Windows Messages in a Service Application?? i.e., get my service application to responde to WM messages..
    :

    If you created an ATL/COM Service program using VC++ 6.0 Class Wizzard, then it already does that.
    [code]

    void CServiceModule::Run()
    {
    _Module.dwThreadID = GetCurrentThreadId();

    HRESULT hr = CoInitialize(NULL);
    // If you are running on NT 4.0 or higher you can use the following call
    // instead to make the EXE free threaded.
    // This means that calls come in on a random RPC thread
    // HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_SPEED_OVER_MEMORY);

    _ASSERTE(SUCCEEDED(hr));

    // This provides a NULL DACL which will allow access to everyone.
    CSecurityDescriptor sd;
    sd.InitializeFromThreadToken();
    hr = CoInitializeSecurity(sd, -1, NULL, NULL,
    RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
    _ASSERTE(SUCCEEDED(hr));

    hr = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, REGCLS_MULTIPLEUSE);
    _ASSERTE(SUCCEEDED(hr));

    LogEvent(_T("Service started"));
    if (m_bService)
    SetServiceStatus(SERVICE_RUNNING);

    [red]
    MSG msg;
    while (GetMessage(&msg, 0, 0, 0))
    DispatchMessage(&msg);
    [/red]
    _Module.RevokeClassObjects();

    CoUninitialize();
    }

    [/code]



  • I'm using this from the net "Beeper Service", however, with WinMain() as entry:

    [code]
    #include
    #include

    TCHAR* serviceName = TEXT("Beeper Service");
    SERVICE_STATUS serviceStatus;
    SERVICE_STATUS_HANDLE serviceStatusHandle = 0;
    HANDLE stopServiceEvent = 0;

    void WINAPI ServiceControlHandler( DWORD controlCode )
    {
    switch ( controlCode )
    {
    case SERVICE_CONTROL_INTERROGATE:
    break;

    case SERVICE_CONTROL_SHUTDOWN:
    case SERVICE_CONTROL_STOP:
    serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
    SetServiceStatus( serviceStatusHandle, &serviceStatus );

    SetEvent( stopServiceEvent );
    return;

    case SERVICE_CONTROL_PAUSE:
    break;

    case SERVICE_CONTROL_CONTINUE:
    break;

    default:
    if ( controlCode >= 128 && controlCode <= 255 )
    // user defined control code
    break;
    else
    // unrecognised control code
    break;
    }

    SetServiceStatus( serviceStatusHandle, &serviceStatus );
    }

    void WINAPI ServiceMain( DWORD /*argc*/, TCHAR* /*argv*/[] )
    {
    // initialise service status
    serviceStatus.dwServiceType = SERVICE_WIN32;
    serviceStatus.dwCurrentState = SERVICE_STOPPED;
    serviceStatus.dwControlsAccepted = 0;
    serviceStatus.dwWin32ExitCode = NO_ERROR;
    serviceStatus.dwServiceSpecificExitCode = NO_ERROR;
    serviceStatus.dwCheckPoint = 0;
    serviceStatus.dwWaitHint = 0;

    serviceStatusHandle = RegisterServiceCtrlHandler( serviceName, ServiceControlHandler );

    if ( serviceStatusHandle )
    {
    // service is starting
    serviceStatus.dwCurrentState = SERVICE_START_PENDING;
    SetServiceStatus( serviceStatusHandle, &serviceStatus );

    // do initialisation here
    stopServiceEvent = CreateEvent( 0, FALSE, FALSE, 0 );

    // running
    serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
    serviceStatus.dwCurrentState = SERVICE_RUNNING;
    SetServiceStatus( serviceStatusHandle, &serviceStatus );

    do
    {
    Beep( 1000, 100 );
    }
    while ( WaitForSingleObject( stopServiceEvent, 5000 ) == WAIT_TIMEOUT );

    // service was stopped
    serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
    SetServiceStatus( serviceStatusHandle, &serviceStatus );

    // do cleanup here
    CloseHandle( stopServiceEvent );
    stopServiceEvent = 0;

    // service is now stopped
    serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
    serviceStatus.dwCurrentState = SERVICE_STOPPED;
    SetServiceStatus( serviceStatusHandle, &serviceStatus );
    }
    }

    void RunService()
    {
    SERVICE_TABLE_ENTRY serviceTable[] =
    {
    { serviceName, ServiceMain },
    { 0, 0 }
    };

    StartServiceCtrlDispatcher( serviceTable );
    }

    void InstallService()
    {
    SC_HANDLE serviceControlManager = OpenSCManager( 0, 0, SC_MANAGER_CREATE_SERVICE );

    if ( serviceControlManager )
    {
    TCHAR path[ _MAX_PATH + 1 ];
    if ( GetModuleFileName( 0, path, sizeof(path)/sizeof(path[0]) ) > 0 )
    {
    SC_HANDLE service = CreateService( serviceControlManager,
    serviceName, serviceName,
    SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
    SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, path,
    0, 0, 0, 0, 0 );
    if ( service )
    CloseServiceHandle( service );
    }

    CloseServiceHandle( serviceControlManager );
    }
    }

    void UninstallService()
    {
    SC_HANDLE serviceControlManager = OpenSCManager( 0, 0, SC_MANAGER_CONNECT );

    if ( serviceControlManager )
    {
    SC_HANDLE service = OpenService( serviceControlManager,
    serviceName, SERVICE_QUERY_STATUS | DELETE );
    if ( service )
    {
    SERVICE_STATUS serviceStatus;
    if ( QueryServiceStatus( service, &serviceStatus ) )
    {
    if ( serviceStatus.dwCurrentState == SERVICE_STOPPED )
    DeleteService( service );
    }

    CloseServiceHandle( service );
    }

    CloseServiceHandle( serviceControlManager );
    }
    }


    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
    {


    //Step 1: Registering the Window Class
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = 0;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wc))
    { fprintf (ptrFile,"error: windows registration failed!
    ");
    //MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
    return 0;
    }

    // Step 2: Creating the Window
    hwnd = CreateWindowEx(
    WS_EX_CLIENTEDGE,
    g_szClassName,
    "app.exe",
    WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
    NULL, NULL, hInstance, NULL);

    if(hwnd == NULL)
    { fprintf (ptrFile,"error: window creation failed
    ");
    //MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
    return 0;
    }



    //ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    WTSRegisterSessionNotification(hwnd, NOTIFY_FOR_ALL_SESSIONS);
    //SendMessage(hwnd,WM_CLOSE,0,0);


    if ( lstrcmpi( lpCmdLine, TEXT("install") ) == 0 )
    {
    InstallService();
    }
    else if (lstrcmpi( lpCmdLine, TEXT("uninstall") ) == 0 )
    {
    UninstallService();
    }

    RunService();


    // Step 3: The Message Loop
    while(GetMessage(&Msg, NULL, 0, 0) > 0 )
    {
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);
    }
    return Msg.wParam;
    }


    [/code]
  • [b][red]This message was edited by stober at 2003-8-6 10:8:34[/red][/b][hr]
    That's already doing it too. See [red]RED[/red] below.

    : I'm using this from the net "Beeper Service", however, with WinMain() as entry:
    :
    : [code]
    : #include
    : #include
    :
    : TCHAR* serviceName = TEXT("Beeper Service");
    : SERVICE_STATUS serviceStatus;
    : SERVICE_STATUS_HANDLE serviceStatusHandle = 0;
    : HANDLE stopServiceEvent = 0;
    :
    : void WINAPI ServiceControlHandler( DWORD controlCode )
    : {
    : switch ( controlCode )
    : {
    : case SERVICE_CONTROL_INTERROGATE:
    : break;
    :
    : case SERVICE_CONTROL_SHUTDOWN:
    : case SERVICE_CONTROL_STOP:
    : serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
    : SetServiceStatus( serviceStatusHandle, &serviceStatus );
    :
    : SetEvent( stopServiceEvent );
    : return;
    :
    : case SERVICE_CONTROL_PAUSE:
    : break;
    :
    : case SERVICE_CONTROL_CONTINUE:
    : break;
    :
    : default:
    : if ( controlCode >= 128 && controlCode <= 255 )
    : // user defined control code
    : break;
    : else
    : // unrecognised control code
    : break;
    : }
    :
    : SetServiceStatus( serviceStatusHandle, &serviceStatus );
    : }
    :
    : void WINAPI ServiceMain( DWORD /*argc*/, TCHAR* /*argv*/[] )
    : {
    : // initialise service status
    : serviceStatus.dwServiceType = SERVICE_WIN32;
    : serviceStatus.dwCurrentState = SERVICE_STOPPED;
    : serviceStatus.dwControlsAccepted = 0;
    : serviceStatus.dwWin32ExitCode = NO_ERROR;
    : serviceStatus.dwServiceSpecificExitCode = NO_ERROR;
    : serviceStatus.dwCheckPoint = 0;
    : serviceStatus.dwWaitHint = 0;
    :
    : serviceStatusHandle = RegisterServiceCtrlHandler( serviceName, ServiceControlHandler );
    :
    : if ( serviceStatusHandle )
    : {
    : // service is starting
    : serviceStatus.dwCurrentState = SERVICE_START_PENDING;
    : SetServiceStatus( serviceStatusHandle, &serviceStatus );
    :
    : // do initialisation here
    : stopServiceEvent = CreateEvent( 0, FALSE, FALSE, 0 );
    :
    : // running
    : serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
    : serviceStatus.dwCurrentState = SERVICE_RUNNING;
    : SetServiceStatus( serviceStatusHandle, &serviceStatus );
    :
    : do
    : {
    : Beep( 1000, 100 );
    : }
    : while ( WaitForSingleObject( stopServiceEvent, 5000 ) == WAIT_TIMEOUT );
    :
    : // service was stopped
    : serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
    : SetServiceStatus( serviceStatusHandle, &serviceStatus );
    :
    : // do cleanup here
    : CloseHandle( stopServiceEvent );
    : stopServiceEvent = 0;
    :
    : // service is now stopped
    : serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
    : serviceStatus.dwCurrentState = SERVICE_STOPPED;
    : SetServiceStatus( serviceStatusHandle, &serviceStatus );
    : }
    : }
    :
    : void RunService()
    : {
    : SERVICE_TABLE_ENTRY serviceTable[] =
    : {
    : { serviceName, ServiceMain },
    : { 0, 0 }
    : };
    :
    : StartServiceCtrlDispatcher( serviceTable );
    : }
    :
    : void InstallService()
    : {
    : SC_HANDLE serviceControlManager = OpenSCManager( 0, 0, SC_MANAGER_CREATE_SERVICE );
    :
    : if ( serviceControlManager )
    : {
    : TCHAR path[ _MAX_PATH + 1 ];
    : if ( GetModuleFileName( 0, path, sizeof(path)/sizeof(path[0]) ) > 0 )
    : {
    : SC_HANDLE service = CreateService( serviceControlManager,
    : serviceName, serviceName,
    : SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
    : SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, path,
    : 0, 0, 0, 0, 0 );
    : if ( service )
    : CloseServiceHandle( service );
    : }
    :
    : CloseServiceHandle( serviceControlManager );
    : }
    : }
    :
    : void UninstallService()
    : {
    : SC_HANDLE serviceControlManager = OpenSCManager( 0, 0, SC_MANAGER_CONNECT );
    :
    : if ( serviceControlManager )
    : {
    : SC_HANDLE service = OpenService( serviceControlManager,
    : serviceName, SERVICE_QUERY_STATUS | DELETE );
    : if ( service )
    : {
    : SERVICE_STATUS serviceStatus;
    : if ( QueryServiceStatus( service, &serviceStatus ) )
    : {
    : if ( serviceStatus.dwCurrentState == SERVICE_STOPPED )
    : DeleteService( service );
    : }
    :
    : CloseServiceHandle( service );
    : }
    :
    : CloseServiceHandle( serviceControlManager );
    : }
    : }
    :
    :
    : int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    : LPSTR lpCmdLine, int nCmdShow)
    : {
    :
    :
    : //Step 1: Registering the Window Class
    : wc.cbSize = sizeof(WNDCLASSEX);
    : wc.style = 0;
    : wc.lpfnWndProc = WndProc;
    : wc.cbClsExtra = 0;
    : wc.cbWndExtra = 0;
    : wc.hInstance = hInstance;
    : wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    : wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    : wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    : wc.lpszMenuName = NULL;
    : wc.lpszClassName = g_szClassName;
    : wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    :
    : if(!RegisterClassEx(&wc))
    : { fprintf (ptrFile,"error: windows registration failed!
    ");
    : //MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
    : return 0;
    : }
    :
    : // Step 2: Creating the Window
    : hwnd = CreateWindowEx(
    : WS_EX_CLIENTEDGE,
    : g_szClassName,
    : "app.exe",
    : WS_OVERLAPPEDWINDOW,
    : CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
    : NULL, NULL, hInstance, NULL);
    :
    : if(hwnd == NULL)
    : { fprintf (ptrFile,"error: window creation failed
    ");
    : //MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
    : return 0;
    : }
    :
    :
    :
    : //ShowWindow(hwnd, nCmdShow);
    : UpdateWindow(hwnd);
    :
    : WTSRegisterSessionNotification(hwnd, NOTIFY_FOR_ALL_SESSIONS);
    : //SendMessage(hwnd,WM_CLOSE,0,0);
    :
    :
    : if ( lstrcmpi( lpCmdLine, TEXT("install") ) == 0 )
    : {
    : InstallService();
    : }
    : else if (lstrcmpi( lpCmdLine, TEXT("uninstall") ) == 0 )
    : {
    : UninstallService();
    : }
    :
    : RunService();
    :
    :
    : // Step 3: The Message Loop
    [red]
    : while(GetMessage(&Msg, NULL, 0, 0) > 0 )
    : {
    : TranslateMessage(&Msg);
    : DispatchMessage(&Msg);
    : }
    [/red]
    : return Msg.wParam;
    : }
    :
    :
    : [/code]
    :



  • [b][red]This message was edited by Danty at 2003-8-6 14:59:27[/red][/b][hr]
    Ok. I want the service to process the red code! So, does it make sence to replace:

    [code]
    [blue]
    do
    : {
    : Beep( 1000, 100 );
    : }
    : while ( WaitForSingleObject( stopServiceEvent, 5000 ) == WAIT_TIMEOUT );
    [/blue]
    [/code]

    with the red code?


    I just want a service continuously checking for WM messages, and based on these messages updates a database.



    : : // Step 3: The Message Loop
    : [red]
    : : while(GetMessage(&Msg, NULL, 0, 0) > 0 )
    : : {
    : : TranslateMessage(&Msg);
    : : DispatchMessage(&Msg);
    : : }
    : [/red]



  • : Ok. I want the service to process the red code! So, does it make sence to replace:
    :
    : [code]
    : [blue]
    : do
    : : {
    : : Beep( 1000, 100 );
    : : }
    : : while ( WaitForSingleObject( stopServiceEvent, 5000 ) == WAIT_TIMEOUT );
    : [/blue]
    : [/code]
    :
    : with the red code?
    :
    :
    : I just want a service continuously checking for WM messages, and based on these messages updates a database.
    :
    :
    :
    : : : // Step 3: The Message Loop
    : : [red]
    : : : while(GetMessage(&Msg, NULL, 0, 0) > 0 )
    : : : {
    : : : TranslateMessage(&Msg);
    : : : DispatchMessage(&Msg);
    : : : }
    : : [/red]
    :
    Sounds like you want ot put your code inside the GetMessage loop. GetMessage will wait until it has something posted to it, the continue. If you want the code to beep everytime a message is received, put your beep call inside the GetMessage loop.
    BTW, that's going to get noisy real fast :-)
  • All I want to do is have a program that runs in the background and checks for WM messages. I want that program to start whenever the computer starts i.e. as a service.

    My program would check for WM_WTSSESSION_CHANGE, and update a database via ODBC.


    Now, it won't work if I just write a windows application and have start in startup, cause I am acctually looking for WTS_SESSION_LOGOFF and WTS_CONSOLE_DISCONNECT in WM_WTSSESSION_CHANGE.
  • : All I want to do is have a program that runs in the background and checks for WM messages. I want that program to start whenever the computer starts i.e. as a service.
    :
    : My program would check for WM_WTSSESSION_CHANGE, and update a database via ODBC.
    :
    :
    : Now, it won't work if I just write a windows application and have start in startup, cause I am acctually looking for WTS_SESSION_LOGOFF and WTS_CONSOLE_DISCONNECT in WM_WTSSESSION_CHANGE.
    :
    Do you have the Spy tool that comes with Visual Studio?
  • [b][red]This message was edited by Danty at 2003-8-7 20:47:15[/red][/b][hr]
    Yes I do have a Spy tool of VSC++6.0!! Using it, I can't find the window name when the service is running. But under TaskManager's process, I can the myservice.exe running! Further, within the service, I do test for the created window handle, and it is fine, however, that window does not exist if I try to FindWindow from another exe program i created.


    The problem is, now that I have solved other troubling problems, is I believe that there is no message queue created for the service!

    So, any posted messages(from another exe file) to the threadID (using spy tool and threadId return from the service) don't make it to the queue.

    So, how can I determine if a message queue exists? or perhaps create one if does not exist!!

    : :
    : Do you have the Spy tool that comes with Visual Studio?
    :



Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories