Message Box Example (C++)

This C++ example shows how to create a task that is scheduled to show a message box when an event occurs. The task contains an event trigger that specifies an event query, which subscribes to an event from the Windows Event Log service. When the event occurs, the task is triggered. The task also contains an action that specifies the task to show a message box. The task is registered using an interactive logon type for the security context of the task, which mean the task will execute if the user who registered the task is logged on and an event is received.

The following procedure describes how to schedule a task to show a message box when an event occurs.

Aa381915.wedge(en-us,VS.85).gifTo schedule a task to show a message box when an event occurs

  1. Initialize COM and set general COM security.

  2. Create the ITaskService object.

    This object allows you to create tasks in a specified task folder.

  3. Get a task folder to create a task in.

    Use the ITaskService::GetFolder method to get the folder, and the ITaskService::NewTask method to create the ITaskDefinition object.

  4. Define information about the task using the ITaskDefinition object, such as the registration information for the task and the task settings.

    Use the RegistrationInfo property of ITaskDefinition and other properties of the ITaskDefinition interface to define the task information.

  5. Create an event trigger using the Triggers property of ITaskDefinition to access the ITriggerCollection for the task.

    Use the ITriggerCollection::Create method (specifying the type of trigger you want to create) to create an event trigger. This allows you to set the event query to subscribe to events. For information about how to create an event query, see Event Selection.

    You can also specify named XPath queries in the ValueQueries property of IEventTrigger. Each specified XPath query is applied to the last matching event XML that is returned from the subscription query specified in the Subscription property of IEventTrigger. The name of the query can be used as a variable in the message of an IShowMessageAction action.

  6. Create an action for the task to execute by using the Actions property of ITaskDefinition to access the IActionCollection interface for the task.

    Use the IActionCollection::Create method to specify the type of action that you want to create. This example uses an IShowMessageAction object, which represents an action that shows a message box.

  7. Register the task using the ITaskFolder::RegisterTaskDefinition method. The task is registered using an interactive logon type for the security context of the task, which mean the task will execute if the user who registered the task is logged on and an event is received.

The following C++ code example shows how to schedule a task to show a message box when a level 4 event is logged in the System event log.

/********************************************************************
 This sample schedules a task to show a message box
 when an event occurs. 
********************************************************************/

#define _WIN32_DCOM
#include <iostream>
#include <windows.h>
#include <stdio.h>

#include <comdef.h>
# pragma comment(lib, \"comsupp.lib\")

//  Include the task header file.
#include <taskschd.h>
# pragma comment(lib, \"taskschd.lib\")

using namespace std;

int __cdecl wmain()
{
    //  ------------------------------------------------------
    //  Initialize COM.
    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if( FAILED(hr) )
    {
        printf("\nCoInitializeEx failed: %x", hr );
        return 1;
    }

    //  Set general COM security levels.
    hr = CoInitializeSecurity(
        NULL,
        -1,
        NULL,
        NULL,
        RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL,
        0,
        NULL);

    if( FAILED(hr) )
    {
        printf("\nCoInitializeSecurity failed: %x", hr );
        CoUninitialize();
        return 1;
    }

    //  ------------------------------------------------------
    //  Create a name for the task.
    LPCWSTR wszTaskName = L"Message Box Test Task";


    //  ------------------------------------------------------
    //  Create an instance of the Task Service. 
    ITaskService *pService = NULL;
    hr = CoCreateInstance( CLSID_TaskScheduler,
                           NULL,
                           CLSCTX_INPROC_SERVER,
                           IID_ITaskService,
                           (void**)&pService );  
    if (FAILED(hr))
    {
          printf("Failed to CoCreate an instance of the TaskService class: %x", hr);
          CoUninitialize();
          return 1;
    }
        
    //  Connect to the task service.
    hr = pService->Connect(_variant_t(), _variant_t(),
        _variant_t(), _variant_t());
    if( FAILED(hr) )
    {
        printf("ITaskService::Connect failed: %x", hr );
        pService->Release();
        CoUninitialize();
        return 1;
    }

    //  ------------------------------------------------------
    //  Get the pointer to the root task folder.  This folder will hold the
    //  new task that is registered.
    ITaskFolder *pRootFolder = NULL;
    hr = pService->GetFolder( _bstr_t( L"\\") , &pRootFolder );
    if( FAILED(hr) )
    {
        printf("Cannot get Root Folder pointer: %x", hr );
        pService->Release();
        CoUninitialize();
        return 1;
    }
    
    // If the same task exists, remove it.
    pRootFolder->DeleteTask( _bstr_t( wszTaskName), 0  );
    
    //  Create the task definition object to create the task.
    ITaskDefinition *pTask = NULL;

    hr = pService->NewTask( 0, &pTask );
    pService->Release();
    if (FAILED(hr))
    {
        printf("Failed to create a new instance of ITaskDefinition: %x", hr);
        pRootFolder->Release();
        CoUninitialize();
        return 1;
    }

        
    //  ------------------------------------------------------
    //  Get the registration info for setting the identification.
    IRegistrationInfo *pRegInfo= NULL;
    hr = pTask->get_RegistrationInfo( &pRegInfo );
    if( FAILED(hr) )
    {
        printf("\nCannot get IRegistrationInfo pointer: %x", hr );
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return 1;
    }
    
    hr = pRegInfo->put_Author( L"Author Name" );
    if( FAILED(hr) )
    {
        printf("\nCannot put author info: %x", hr );
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return 1;
    }

    pRegInfo->Release();  // COM clean up.  Pointer is no longer used.

    //  ------------------------------------------------------
    //  Create the settings for the task
    ITaskSettings *pSettings = NULL;
    hr = pTask->get_Settings( &pSettings );
    if( FAILED(hr) )
    {
        printf("\nCannot get settings pointer: %x", hr );
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return 1;
    }
    
    //  Set setting values for the task.  
    hr = pSettings->put_StartWhenAvailable(VARIANT_TRUE);
    if( FAILED(hr) )
    {
        printf("\nCannot put setting info: %x", hr );
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return 1;
    }

    pSettings->Release();  // COM clean up.  Pointer is no longer used.

    //  ------------------------------------------------------
    //  Get the trigger collection to insert the event trigger.
    ITriggerCollection *pTriggerCollection = NULL;
    hr = pTask->get_Triggers( &pTriggerCollection );
    if( FAILED(hr) )
    {
        printf("\nCannot get trigger collection: %x", hr );
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return 1;
    }

    //  Create the event trigger for the task.
    ITrigger *pTrigger = NULL;
    
    hr = pTriggerCollection->Create( TASK_TRIGGER_EVENT, &pTrigger );
    pTriggerCollection->Release();     
    if( FAILED(hr) )
    {
        printf("\nCannot add event trigger to the task: %x", hr );
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return 1;
    }

    IEventTrigger *pEventTrigger = NULL;
    hr = pTrigger->QueryInterface( 
        IID_IEventTrigger, (void**) &pEventTrigger );
    pTrigger->Release();
       if( FAILED(hr) )
    {
        printf("\nQueryInterface call for IEventTrigger failed: %x", hr );
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return 1;
    }
    
    ITaskNamedValueCollection *pValueQueries = NULL;
    hr = pEventTrigger->get_ValueQueries( &pValueQueries );
    if( FAILED(hr) )
    {
        printf("\nCannot get value queries: %x", hr);
        pEventTrigger->Release();
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return 1;
    }    
            
    ITaskNamedValuePair* pNamedValuePair = NULL;
    hr = pValueQueries->Create(
       _bstr_t( L"eventID"), _bstr_t( L"Event/System/EventRecordID"), &pNamedValuePair);
    pValueQueries->Release();
    pNamedValuePair->Release();
    if( FAILED(hr) )
    {
        printf("\nCannot create name value pair: %x", hr);
        pEventTrigger->Release();
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return 1;
    }
    
    hr = pEventTrigger->put_Id( _bstr_t( L"Trigger1" ) );
    if( FAILED(hr) )
       printf("\nCannot put the trigger ID: %x", hr);

    //  Set the task to start at a certain time. The time 
    //  format should be YYYY-MM-DDTHH:MM:SS(+-)(timezone).
    //  For example, the start boundary below
    //  is January 1st 2005 at 12:05
    hr = pEventTrigger->put_StartBoundary( _bstr_t(L"2005-01-01T12:05:00") );
    if( FAILED(hr) )
        printf("\nCannot put the trigger start boundary: %x", hr);

    hr = pEventTrigger->put_EndBoundary( _bstr_t(L"2015-05-02T08:00:00") );
    if( FAILED(hr) )
        printf("\nCannot put the trigger end boundary: %x", hr);

    //  Define the delay for the event trigger (10 seconds).
    hr = pEventTrigger->put_Delay( _bstr_t(L"PT10S") );
    if( FAILED(hr) )
        printf("\nCannot put the trigger delay: %x", hr);

    //  Define the event query for the event trigger.
    //  The following query string defines a subscription to all
    //  level 4 events in the System channel.
    hr = pEventTrigger->put_Subscription( 
        L"<QueryList> <Query Id='1'> <Select Path='System'>*[System/Level=4]</Select></Query></QueryList>" );    
    pEventTrigger->Release();    
    if( FAILED(hr) )
    {
        printf("\nCannot put the event query: %x", hr);  
        pRootFolder->Release();
        pTask->Release();
        pValueQueries->Release();
        CoUninitialize();
        return 1;
    }              

    //  ------------------------------------------------------
    //  Add an action to the task.
    //  This task will show a message box.     
    IActionCollection *pActionCollection = NULL;

    //  Get the task action collection pointer.
    hr = pTask->get_Actions( &pActionCollection );
    if( FAILED(hr) )
    {
        printf("\nCannot get task action collection pointer: %x", hr );
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return 1;
    }
        
    //  Create the action, specifying that it will show a message box.
    IAction *pAction = NULL;
    hr = pActionCollection->Create( TASK_ACTION_SHOW_MESSAGE, &pAction );
    pActionCollection->Release();
    if( FAILED(hr) )
    {
        printf("\nCannot create the action: %x", hr );
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return 1;
    }

    IShowMessageAction *pShowMessageAction = NULL;
    hr = pAction->QueryInterface( 
        IID_IShowMessageAction, (void**) &pShowMessageAction );
    pAction->Release();
    if( FAILED(hr) )
    {
        printf("\nQueryInterface call failed for IShowMessageAction: %x", hr );
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return 1;
    }

    //  Set the properties of the message box action.
     hr = pShowMessageAction->put_Title(_bstr_t(L"Message Box Title"));
    if( FAILED(hr) )
    {
        printf("\nCannot put the message box title: %x", hr );
        pShowMessageAction->Release();
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return 1;
    }
    
    // This message shows the event ID.  The $(eventID) variable will be replaced
    // with the event ID (the variable name came from the trigger's ValueQueries
    // property).
    hr = pShowMessageAction->put_MessageBody(
        _bstr_t(L"This is the event ID: $(eventID)"));
    if( FAILED(hr) )
    {
        printf("\nCannot put the message box body: %x", hr );
        pShowMessageAction->Release();
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return 1;
    }
    
    // COM clean up.  Pointer is no longer used.
    pShowMessageAction->Release();

    //  ------------------------------------------------------
    //  Save the task in the root folder.
    IRegisteredTask *pRegisteredTask = NULL;
    hr = pRootFolder->RegisterTaskDefinition(
            _bstr_t( wszTaskName ),
            pTask,
            TASK_CREATE_OR_UPDATE, 
            _variant_t(), 
            _variant_t(), 
            TASK_LOGON_INTERACTIVE_TOKEN,
            _variant_t(),
            &pRegisteredTask);
    if( FAILED(hr) )
    {
        printf("\nError saving the Task : %x", hr );
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return 1;
    }
    
    printf("\n Success! Task successfully registered. " );

    //  Clean up.
    pRootFolder->Release();
    pTask->Release();
    pRegisteredTask->Release();
    CoUninitialize();

    return 0;
}

Using the Task Scheduler

 

 

Send comments about this topic to Microsoft

Build date: 10/16/2012