Google Desktop
 Google Desktop Event Notification Developer Guide

For Users
  Download Plug-ins
  Desktop Search Forum

For Developers
  Plug-in Development
  Download SDK
  Developer Guide
    Index API
    Query API
    Display API
      Script API
      Communication API
      Plug-in Design Guidelines
      Plug-in Tutorials
        Using Wizard
        Using Helper Framework
        Using ActiveX
    Action API
    Event API
    Plug-in Installer
  Submit Software
  Developer Forum
  Desktop Blog

Contents

Overview

Event Notification Developer API

GoogleDesktopAPI.idl


Overview

Getting Started

The Google Desktop Event Notification Framework allows plug-ins to receive notifications when new items are being indexed.

To use event notifications you will need, in addition to the information in this document:

  • Sufficient access to write a plug-in for your application and an installer for it.
  • Programming knowledge of the Microsoft Windows Component Object Model (COM).

Development Process Overview

To develop an Event Notification plug-in, start by downloading the SDK, in particular the GoogleDesktopAPI.idl file. We recommend developing your application with Microsoft Visual Studio.

You will then need to write code to:

  • Register your application with Google Desktop (required).
  • Subscribe to receive event notifications and implement the required callbacks.
  • Unregister your application with Google Desktop when your application uninstalls.

We recommend that you look over the sample code provided with the SDK. Please note that the sample code examples have their GUIDs hardcoded, so if you choose to reuse code from there you must change the interfaceIDs, classIDs, and libIDs to ones valid for your application.

Back to top
Event Notification Developer API

Registering Event Notification Components

Google Desktop will not accept unregistered components. The Event Notification component registration is a one-time process done using the IGoogleDesktopRegistrar interface, and should be done during component installation. As part of the registration process, the component must provide its GUID as well as information about itself.

As part of its uninstallation process, a component should unregister itself with Google Desktop.

Component Registration Interface Summary

The following summarizes the interface and its methods. All method return values are of type HRESULT.

interface IGoogleDesktopRegistrar: IDispatch
  • Note: Components are required to to call this interface to register themselves with Google Desktop before they can interact with any APIs or other provided services.
  • Note: The registration process consists of a call to StartComponentRegistration followed by individual registrations for various services obtained through GetRegistrationInterface and finished by a call to FinishComponentRegistration. For event components, the registration progid is "GoogleDesktop.EventRegistration" and the interface is IGoogleDesktopRegisterEventPlugin.
  • StartComponentRegistration: Must be invoked by any component to initiate the registration process.
    • Arguments:
      • BSTR component_guid_or_progid: The component's GUID or ProgID.
      • VARIANT component_description: A SAFEARRAY of pairs, where the first element is a descriptive parameter name and the second element is that parameter's value. The method expects only the following three required parameters, which should be given in this order.
        • "Title": Component title that will be displayed on the GD preferences page.
        • "Description": Component description that will be displayed on the GD preferences page.
        • "Icon": A string pointing to an ICON resource, of the form "c:\program files\boo\comp.dll,23". This icon may be used to indicate the component and its results on various GD pages.
    • Returns:
      • S_OK if successful.
      • E_COMPONENT_ALREADY_REGISTERED if this component has already been registered with GD.
      • Appropriate error on failure, such as an unregistered component classID or appID, component prohibited by policy, etc.

  • GetRegistrationInterface: Provides the requested type of registration interface.
    • Arguments:
      • BSTR registration_type: a stringified CLSID or a progid to the type of registration required.
      • [out, retval] IUnknown **registration_interface: provides the requested registration mechanism.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.

  • FinishComponentRegistration: Must be invoked to finish the registration process.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure, such as an unregistered component classID or appID, component prohibited by policy, etc.

  • UnregisterComponent
    • Arguments:
      • BSTR component_guid_or_progid: the same GUID used when registering the component.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
Component Registration Code Template

The following template demonstrates how a component can register for event notifications. Note that this registration should only be done once, not every time the plug-in starts.

To register a component:

  CComPtr<IGoogleDesktopRegistrar> spRegistrar;
  HRESULT hr;
  
  hr = spRegistrar.CoCreateInstance(CLSID_GoogleDesktopRegistrar);
  
  if (SUCCEEDED(hr)) {
    ATLASSERT(spRegistrar != NULL);
    
    // Component description is 6 strings
    CComSafeArray<VARIANT> arr_descr(6);

    arr_descr.SetAt(0, CComVariant(L"Title"));
    arr_descr.SetAt(1, CComVariant(L"A sample event notification plug-in"));
    arr_descr.SetAt(2, CComVariant(L"Description"));
    arr_descr.SetAt(3, CComVariant(L"Implements sample event notifications"));
    arr_descr.SetAt(4, CComVariant(L"Icon"));
    arr_descr.SetAt(5, CComVariant(L",1"));

    // our CLSID in string format
    CComBSTR our_clsid(clsid);
    
    // Wrap description array in variant
    CComVariant descr(arr_descr.m_psa);

    // and register
    hr = spRegistrar->StartComponentRegistration(our_clsid, descr);
    if (FAILED(hr))
      return hr;

    // success, now register as an event notification component.
    CComPtr<IGoogleDesktopRegisterEventPlugin> spRegistration;

    CComBSTR event_registrar_progid("GoogleDesktop.EventRegistration");
    hr = spRegistrar->GetRegistrationInterface(event_registrar_progid,
      reinterpret_cast<IUnknown**>(&spRegistration));
    ATLASSERT(FAILED(hr) || spRegistration);

    if (SUCCEEDED(hr)) {
      // registration cookie that will be used later on 
      // to subscribe to event notifications
      long cookie = 0;
      hr = spRegistration->RegisterPlugin(CComBSTR(PLUGIN_GUID), &cookie);

      if (SUCCEEDED(hr)) {
        hr = spRegistrar->FinishComponentRegistration();
      }
      
      // store the registration cookie
      if (SUCCEEDED(hr)) {
        hr = StoreRegistrationCookie(cookie);
      }      
    }

To unregister a component:

  CComPtr<IGoogleDesktopRegistrar> spRegistrar;
  HRESULT hr;
  
  hr = spRegistrar.CoCreateInstance(CLSID_GoogleDesktopRegistrar);
  
  if (SUCCEEDED(hr)) { 
    // our CLSID in string format
    CComBSTR bstrClsid(clsid);
  
    hr = spRegistrar->UnregisterComponent(bstrClsid);
  }
Back to top

Using the Event Notification Framework

After a successful registration with Google Desktop, a component can use the Event Notification APIs to subscribe to receive notifications about items being indexed as well as filter which events to receive based on specific criteria.

Subscribing for Event Notifications

The Event Notification API consists of a set of COM interfaces which control how a subscription behaves. The entry point to the Event Notification Framework is the IGoogleDesktopEventPublisher interface.

interface IGoogleDesktopEventPublisher: IDispatch
  • Subscribe: Subscribe to start receiving notification events.
    • Arguments:
      • long registration_cookie: The cookie received from the registration procedure (see IGoogleDesktopRegisterEventPlugin).
      • IUnknown* subscriber: The object that will receive notification calls when events are received. Out-of-proc subscribers implement IDispatch on this object and receive calls on either a method named "OnNewEvent" or the default method that has the dispid DISPID_VALUE. OnNewEvent accepts a single argument of type IGoogleDesktopNotifyEvent. In-proc subscribers can implement a private interface, IGDSEventSubscriber:IUnknown.
      • [out, retval] IGoogleDesktopEventSubscription** subscription: The subscription object.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
  • Unsubscribe: Invoke to stop receiving notification events and free any associated resources.
    • Arguments:
      • IGoogleDesktopEventSubscription* subscription: The the subscription object.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.

The following interfaces control a subscription. Before events are delivered to subscribers, they must pass through any filters that are active on the subscription.

interface IGoogleDesktopFilterCollection: IDispatch
  • filter_operator: Get/Put property used to decide how multiple filter results are combined.
    • Arguments:
      • GoogleDesktopSubscriptionFilterOperator op: One of the and/or operators (GD_FILTER_OPERATOR_AND, GD_FILTER_OPERATOR_OR).
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
  • negate_result: Get/Put property negates the result of filtering.
    • Arguments:
      • [out, retval] VARIANT_BOOL * not: .
    • Returns: If true, negates the result of filtering
      • S_OK if successful.
      • Appropriate error on failure.
  • AddFilter: Add a new filter for the event stream.
    • Arguments:
      • BSTR progid: The prog id of the filter to add.
      • [in, optional] VARIANT name: Optional filter name.
      • [out, retval] IDispatch** filter: The filter object.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
  • RemoveFilter: Remove a filter from the event stream.
    • Arguments:
      • IDispatch* filter: The filter object.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
  • FindFilter: Find an event filter given a name.
    • Arguments:
      • BSTR filter_name: The filter name.
      • [out, retval] IDispatch** filter: The filter object.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
  • RemoveAllFilters: Remove all filters from the subscription.
    • Arguments:
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
interface IGoogleDesktopEventSubscription: IGoogleDesktopFilterCollection
  • active: Get/Put property used to enable/disable a subscription.
    • Arguments:
      • VARIANT_BOOL event_stream_enabled: Enable/disable switch.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
Filtering Event Notifications

The following interfaces allow the plug-in to filter the event notifications based on specified schemas and the content of schema properties.

interface IGoogleDesktopSchemaFilter: IDispatch
  • AllowNone: Clears all allowed values and disables all event notifications.
    • Arguments:
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
  • Allow: Add the specified schema to the array of allowed schema names.
    • Arguments:
      • BSTR schema_name: Name of the allowed schema.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
  • Disallow: Remove the specified schema from the array of allowed schema names.
    • Arguments:
      • BSTR schema_name: Name of the removed schema.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
  • GetAllowed: Retrieves the array of allowed schema names.
    • Arguments:
      • [out, retval] SAFEARRAY(VARIANT)* schema_names: Array containing the allowed schema names.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
interface IGoogleDesktopSchemaPropertyFilter: IDispatch
  • AddRequiredText: Adds the specified string to the array of strings required in the property.
    • Arguments:
      • BSTR property_name: The property name to filter on.
      • BSTR required: The string required in the property.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
  • AddExcludedText: Adds the specified string to the array of strings excluded from the property.
    • Arguments:
      • BSTR property_name: The property name to filter on.
      • BSTR required: The string excluded from the property.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
  • RemoveRequiredText: Removes the specified string from the array of strings required in the property.
    • Arguments:
      • BSTR property_name: The property name to filter on.
      • BSTR required: The string to be removed.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
  • RemoveExcludedText: Removes the specified string from the array of strings excluded from the property.
    • Arguments:
      • BSTR property_name: The property name to filter on.
      • BSTR required: The string to be removed.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
  • GetRequiredText: Retrieves the array of strings required in the property.
    • Arguments:
      • BSTR property_name: The property name to filter on.
      • [out, retval] SAFEARRAY(VARIANT)* required: Array of strings.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
  • GetExcludedText: Retrieves the array of strings excluded from the property.
    • Arguments:
      • BSTR property_name: The property name to filter on.
      • [out, retval] SAFEARRAY(VARIANT)* excluded: Array of strings.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
  • match_whole_word: Put property that specifies if matching is restricted to whole words.
    • Arguments:
      • [in] VARIANT_BOOL whole: If true, match whole words.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
Receiving an Event Notification

After successfully subscribing to the Event Notification Framework and setting filtering options, a plug-in will be called for each matching event through the subscriber object passed to the IGoogleDesktopEventPublisher.Subscribe method. Event information will be provided through the IGoogleDesktopNotifyEvent interface. interface IGoogleDesktopNotifyEvent: IDispatch

  • GetProperty: Returns the value of a named property.
    • Arguments:
      • BSTR property_name: The property name.
      • [out, retval] VARIANT* property_value: The value of the property.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
  • SchemaName: Get property which holds the name of the schema that the event is derived from.
    • Arguments:
      • [out, retval] BSTR* schema_name: The schema name.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
Event Notification Code Template

The following template demonstrates how a plug-in subscribes to receive event notifications and how to configure the subscription.

		
  //
  // Create an instance of the Google Desktop Event Publisher
  // and set up a subscription
  //
  CComPtr<IGoogleDesktopEventPublisher> publisher;
  hr = publisher.CoCreateInstance(L"GoogleDesktop.EventPublisher.1");

  // A callback object that will receive notifications
  EventCallback callback;

  // The subscription that controls how events are delivered to us
  CComPtr<IGoogleDesktopEventSubscription> subscription;

  if (SUCCEEDED(hr)) {
    // Get the callback object
    CComPtr<IUnknown> callback_identity;
    hr = callback._LocDEQueryInterface(IID_IUnknown,
                                       reinterpret_cast<void**>(&callback_identity));

    // Subscribe
    hr = publisher->Subscribe(cookie, callback_identity, &subscription);
    if (SUCCEEDED(hr)) {
      CComQIPtr<IGoogleDesktopSchemaFilter> schema_filter;    
      
      // Add a schema filter
      CComPtr<IDispatch> disp;
      hr = sub->AddFilter(CComBSTR(L"GoogleDesktop.SchemaFilter"), CComVariant(), &disp);
      if (FAILED(hr))
        return hr;

      // Filter on the Email schema
      schema_filter = disp;
      hr = schema_filter->Allow(CComBSTR(L"Google.Desktop.Email"));

      if (SUCCEEDED(hr)) {
        // Turn on the event stream and start receiving notifications
        subscription->put_active(VARIANT_TRUE);
      }
    }
  }
		

The code template below shows a sample callback implementation through which the plug-in receives notifications. The event information is passed in through an object implementing IGoogleDesktopNotifyEvent.

class EventCallback : 
  public IDispEventSimpleImpl<1, EventCallback, &IID_IDispatch> {
public:
BEGIN_SINK_MAP(EventCallback)
  SINK_ENTRY_INFO(1, IID_IDispatch, DISPID_VALUE, OnNewEvent, &s_OnNewEventInfo)
END_SINK_MAP()

  /**
  * This function gets called by the event framework as this is the default
  * method on our class (DISPID_VALUE).
  */
  STDMETHOD_(void, OnNewEvent)(IDispatch* event) {
    if (event == NULL) {
      _tprintf(_T("Historical indexing has just been done.\n"));
    } else {
      CComQIPtr<IGoogleDesktopNotifyEvent> e(event);
      ATLASSERT(e != NULL);
      CComBSTR schema;
      e->get_SchemaName(&schema);

      CComVariant uri;
      e->GetProperty(CComBSTR(L"uri"), &uri);

      _tprintf(_T("%ls: %ls\n"), schema, uri.vt == VT_BSTR ? uri.bstrVal : L"?");
    }
  }

  static _ATL_FUNC_INFO s_OnNewEventInfo;
};

_ATL_FUNC_INFO EventCallback::s_OnNewEventInfo = {CC_STDCALL, VT_EMPTY, 1, {VT_DISPATCH}};		

Back to top