Google Desktop
 Google Desktop SDK Index API 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 Schemas

GD Developer Indexing API

GoogleDesktopAPI.idl

schemas.xml


Overview

Getting Started

Google Desktop (GD) indexes, caches, and searches content on your computer. Through the GD Software Development Kit's APIs, your applications can send content to the GD engine for indexing and storage. In particular, you can write plug-ins that allow GD to store and search content from applications that it doesn't already handle.

To integrate your application with GD 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 and/or an understanding of your application's file format.
  • Basic programming knowledge of the Microsoft Windows Component Object Model (COM).

Development Process Overview

To develop a GD application, 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 (in any COM compatible language) that uses the GD API to:

  • Register your application with GD (required).
  • Register with GD to handle one or more file extensions (optional).
    • If you do this registration, the GD crawler will notify your plug-in whenever it encounters a file with the registered extension.
  • One of:
    • Create a GD event object from scratch.
    • In response to a GD notification about a file, create a GD event object.
  • Set the event object's property values, and then send it to GD.
  • Unregister your application with GD when your application uninstalls.

We recommend that you look over the sample code provided with the SDK, as well as the basic GD API operation C++ code templates provided in this document. 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.

SDK Overview

The Google Desktop SDK includes the following:

The GD engine processes event objects sent to it by external components. An event object consists of the content data you want the engine to index and store, as well as additional meta-information and properties about that content or the event object.

The Event Schemas specify the allowed event types, and the relevant properties for each event type.

The Developer Indexing API consists of interfaces used to construct event objects and send them to GD, register to receive notifications from the GD crawler, and for registering your application with GD.

Back to top
Event Schemas

Event objects are all defined by event schemas, which specify what information and properties a particular event type can contain. The complete set of event schema definitions is in XML (download XML file). Event schemas are all pre-defined by Google; you cannot add to or modify the schema set. There are event schemas for:

  • Files (with subschemas for text files, web pages, and media files)
  • Email messages
  • Calendar entries
  • Contacts entries
  • Tasks entries
  • Notes entries
  • Journal entries

Each schema contains a set of schema properties. Each property has various attributes such as name, type, required, etc.

Schemas are organized in a parent-child relationship hierarchy, with children inheriting properties from their parent. The current hierarchy consists of three levels, with Google.Desktop.Indexable as the base schema. Schemas are identified by their fully qualified name, such as Google.Desktop.IM.

When constructing an event object, you will first choose the appropriate schema, create an event object based on that schema, and then set its property values. For example, in order to index a text file's content, a component will use the Google.Desktop.TextFile schema to create an event object. The component will then set the event's content property to contain the file's indexable content and specify the content's format (text/plain or text/html) in the format property. It will also set the uri property with the file's location and the last_modified_time property with the file's access time. Those properties are all required; the component may or may not set the optional properties, such as the author or title properties. Remember, Google.Desktop.TextFile inherits properties from both its ancestors, Google.Desktop.Indexable and Google.Desktop.File.

Full XML schema descriptions are given here, with the property type attributes expressed using the Windows VARIANT data types. The following summarizes each schema and its properties, including allowed values and whether a property is required as well as some usage notes. Remember, in the current release, all other schemas inherit properties from Google.Desktop.Indexable. In particular, the required content and format properties for every event object are inherited from there.

Google.Desktop.Indexable

Note: This is an abstract schema. You cannot instantiate any event objects of type Google.Desktop.Indexable. Use one of its descendent schemas instead.

Note: Event objects cannot exceed a size that varies depending on machine characteristics. This averages several hundred thousand KB. If you send too large an event object to GD, GD will first truncate the event object's content property's value until the total event object size is equal to the maximum allowed size. If all of the content property's value has been removed and the event object is still too big, GD will reject the event object.

Property Description Type Required
content Contains the content to be indexed. The content must be in a text format (which can include HTML or similar markup, although GD will only treat HTML markup differently from plain text) not binary data. Note that some items may not have any indexable content, such as media files for which GD only indexes metadata and email messages with no content in their body. For those items, set this property to an empty string.  VT_BSTR Yes
format Mime type of the indexable content, allowed values are text/plain and text/html. VT_BSTR Yes
native_size Size of the indexable content in bytes. Note that for file types for which there is no indexable content but still contain content, such as media files, you should set this property to be the size of the content. For example, for a 10 Megabyte audio file, you wouldn't put the 10 MB of content in an event's content property, but you should set its native_size property to 10000000. VT_UI8 No
thumbnail Thumbnail image of the content. We recommend the image be 109 pixels wide by 75 pixels tall. Image files of more than 20 KB will be rejected with an invalid argument error. If you specify a thumbnail image, you must also set a value for the following thumbnail_format property. VT_ARRAY No
thumbnail_format Mime type of the thumbnail image, allowed values are image/gif, image/jpeg, and image/png. VT_BSTR No
cookie String cookie used to pass additional information identifying the event. VT_BSTR No
cookie_raw Binary cookie. VT_ARRAY No
other_data (New) Contains optional indexable content and metadata. Can be used to index additional data that is separate from the content property VT_BSTR No


Google.Desktop.Email
inherits Google.Desktop.Indexable

Note: In general, you should either only set an email event object's header property with everything in a message's header, or only set the individual header field properties such as subject, to, etc. If you set the header property, the GD engine will parse out the separate fields and their contents. If you specify values for both header and individual field properties, the individual field values will take precedence.

Note: There is currently no property for email attachments. Your plug-in can copy each attachment on an email message to a location on your file system so that the GD crawler will encounter them. Then, if its file extension is handled by GD (or a plug-in), each attachment's content will be indexed and cached by GD. However, the attachment(s) content will not be associated with the email message within either GD or any desktop search results.

Property Description Type Required
mail_header Message's entire mail header as received in the mail envelope. VT_BSTR No
subject Message's Subject: field contents. VT_BSTR No
from Message's From: field contents as it appears in the mail header (we recommend all of it, both address, and if present, the addressee's name). VT_BSTR No
to Message's To: field contents (we recommend all of it, both address and, if present, the addressee's name). VT_BSTR No
cc Message's Cc: field contents (we recommend all of it, both address and, if present, the addressee's name). VT_BSTR No
bcc Message's Bcc: field contents (we recommend all of it, both address and, if present, the addressee's name). VT_BSTR No
replyto Message's ReplyTo: field contents (we recommend all of it, both address and, if present, the addressee's name). VT_BSTR No
received Message's received time in UTC. VT_DATE Yes
folder_name Message's folder name. VT_BSTR No
mail_flags Bit vector flags associated with the email (0x01 = Unread, 0x02 = HasAttachment). VT_UI4 No


Google.Desktop.IM inherits Google.Desktop.Indexable

Note: When setting the inherited content property for IM events, each message should be of the form <name of sender>: <msg>. This allows GD to correctly format the content when displaying it as a result.

Property Description Type Required
conversation_id Id that can be used to group messages that are part of the same conversation. VT_UI4 No
message_time Time when the message was received in UTC. VT_DATE Yes
title Title of the Instant Message. This will usually be your choice, as IMs don't usually have actual titles. VT_BSTR No
user_name Name or handle of the user who is using the computer on which this event is being generated. VT_BSTR No
buddy_name Name or handle of the other user in the conversation. VT_BSTR Yes


Google.Desktop.Contact inherits Google.Desktop.Indexable

Property Description Type Required
uri Unique identifier. VT_BSTR Yes
last_modified_time Time when the contact was last modified. VT_DATE Yes
assistant Contact's assistant's name. VT_BSTR No
birthday Contact's birthday. VT_DATE No
business_address Contact's address at work. VT_BSTR No
business_fax Contact's fax number at work. VT_BSTR No
business_home_page Contact's home page at work. VT_BSTR No
business_phone Contact's phone number at work. VT_BSTR No
categories Whatever categories you want to assign the contact. VT_BSTR No
children_names Contact's children's names. VT_BSTR No
company_name Name of contact's company. VT_BSTR No
company_phone Contact's company's phone number. VT_BSTR No
country Contact's country. VT_BSTR No
department Contact's department at work. VT_BSTR No
display_name Name by which the contact is displayed, such as "Tom (landlord)" VT_BSTR No
email1 Contact's first email address. VT_BSTR No
email2 Contact's second email address. VT_BSTR No
email3 Contact's third email address. VT_BSTR No
folder_name Name of the folder containing this contact. VT_BSTR No
hobbies Contact's hobbies. VT_BSTR No
home_address Contact's home address. VT_BSTR No
home_fax Contact's home fax number. VT_BSTR No
home_phone Contact's home phone number. VT_BSTR No
im_address Contact's IM address. VT_BSTR No
job_title Contact's job title. VT_BSTR No
language Contact's primary language. VT_BSTR No
manager_name Contact's manager's name. VT_BSTR No
mobile_phone Contact's cell or mobile phone number. VT_BSTR No
nickname Contact's nickname. VT_BSTR No
office_location Contact's office location. VT_BSTR No
other_address Any alternative address for the Contact. VT_BSTR No
other_phone Contact's other phone number. VT_BSTR No
pager Contact's pager. VT_BSTR No
personal_home_page Contact's personal home page. VT_BSTR No
primary_fax Contact's primary fax number. VT_BSTR No
primary_phone Contact's primary phone number. VT_BSTR No
profession Contact's profession. VT_BSTR No
spouse Contact's spouse's name. VT_BSTR No
title Contact's title. VT_BSTR No
web_page Contact's web page. VT_BSTR No
wedding_anniversary Contact's wedding anniversary. VT_DATE No

Google.Desktop.Calendar inherits Google.Desktop.Indexable

Property Description Type Required
uri Unique identifier. VT_BSTR Yes
last_modified_time Time when the appointment was last modified. VT_DATE Yes
attendees Names of appointment attendees. VT_BSTR No
categories Whatever categories you want to assign to the appointment. VT_BSTR No
folder_name Name of the folder containing this appointment. VT_BSTR No
location Appointment location. VT_BSTR No
organizer Name of the appointment's organizer. VT_BSTR No
start_date Appointment start time in UTC. VT_DATE Yes
end_date Appointment end time in UTC. VT_DATE Yes
duration Appointment duration in minutes. VT_UI4 No
recurrence_pattern A string describing how this task repeats. The format is a list of ISO 8601 intervals, separated by semicolons (e.g. 06-22-2005 11:00:00 / 06-22-2005 12:00:00; 06-24-2005 13:00:00 / 06-24-2005 15:00:00). VT_UI4 No
title Appointment title. VT_BSTR No

Google.Desktop.Task inherits Google.Desktop.Indexable

Property Description Type Required
uri Unique identifier. VT_BSTR Yes
last_modified_time Time when the task was last modified. VT_DATE Yes
actual_work Actual work completed (in hours). VT_BSTR No
categories Task categories. VT_BSTR No
companies Companies. VT_BSTR No
folder_name Task's folder name. VT_BSTR No
date_completed Date task completed. VT_DATE No
start_date Task start date. VT_DATE No
due_date Task due date. VT_DATE No
importance Task importance (0=low, 1=normal, 2=high). VT_UI4 No
owner Owner of the task. VT_BSTR No
participants Task participants. VT_BSTR No
percent_complete Task percent complete. VT_UI4 No
recurrence_pattern A string describing how this task repeats. The format is a list of ISO 8601 intervals, separated by semicolons (e.g. 06-22-2005 11:00:00 / 06-22-2005 12:00:00; 06-24-2005 13:00:00 / 06-24-2005 15:00:00). VT_UI4 No
total_work Task total work (in hours). VT_UI4 No
status Task status (0=not started, 1=in progress, 2=completed, 3=waiting on others, 4=deferred 5=overdue, 6=rejected). VT_UI4 No
title Task's title. VT_BSTR No


Google.Desktop.Note inherits Google.Desktop.Indexable

Property Description Type Required
uri Unique identifier. VT_BSTR Yes
last_modified_time Time when the note was last modified. VT_DATE Yes
notes Notes. VT_BSTR No
categories Note categories. VT_BSTR No
date Note date. VT_DATE No
folder_name Note's folder name. VT_BSTR No
title Note's title. VT_BSTR No


Google.Desktop.Journal inherits Google.Desktop.Indexable

Property Description Type Required
uri Unique identifier. VT_BSTR Yes
last_modified_time Time when the journal was last modified. VT_DATE Yes
company Journal company. VT_BSTR No
categories Journal categories. VT_BSTR No
company Journal type. VT_BSTR No
folder_name Journal's folder name. VT_BSTR No
start_time Journal start time. VT_DATE No
duration Journal duration (in minutes). VT_UI4 No
title Journal's title. VT_BSTR No
type Journal's type. VT_BSTR No

Google.Desktop.File inherits Google.Desktop.Indexable
Property Description Type Required
uri The file's URI. VT_BSTR Yes
last_modified_time When the file was last modified in UTC. VT_DATE Yes
title What title you choose to give the file, usually its filename. VT_BSTR No
author The file's author. VT_BSTR No


Google.Desktop.WebPage
inherits Google.Desktop.File

Property Description Type Required
bookmarked Specifies if this web page is bookmarked. VT_BOOL No
interaction_period Amount of time the user interacted with the web page. VT_DATE No


Google.Desktop.TextFile inherits Google.Desktop.File

No distinctive properties yet.


Google.Desktop.MediaFile inherits Google.Desktop.File

Property Description Type Required
keywords Keywords associated with the file. VT_BSTR No
width Image or video width in pixels. VT_UI4 No
height Image or video height in pixels. VT_UI4 No
bit_rate Audio content (in either an audio or video file) average bit rate in bits/second. VT_UI4 No
data_rate Data rate for video files in bytes/second. VT_UI4 No
channels Channel count for audio files. VT_UI4 No
comment Comment about the file and its contents. VT_BSTR No
length Music or video file time length in nanoseconds. VT_UI8 No
original_date Original file time stamp from the media device in UTC. VT_DATE No
album_title Music file album title. VT_BSTR No
artist Artist who created/performed the content. VT_BSTR No
genre Genre category. VT_BSTR No
lyrics Music file lyrics. VT_BSTR No
track_number Song's track number on its album. VT_UI4 No
info_tip Info tip as reported from the shell. VT_BSTR No
year_published Year this material was first published. VT_UI4 No
Back to top
GD Developer Indexing API

Registering Indexing Components

Google Desktop will not accept unregistered components. Indexing 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. Please note that indexing components can also use the older style registration mechanism available through the IGoogleDesktopSearchComponentRegister interface, however, it is recommended to use the IGoogleDesktopRegistrar interface especially if registering more than one plug-in type.

As part of its own uninstallation process, a component should unregister itself with GD.

Component Registration Interface Summary

The following summarizes the interfaces and their 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 indexing components the registration progid is "GoogleDesktop.IndexingRegistration" and the interface is IGoogleDesktopRegisterIndexingPlugin.
  • 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.
interface IGoogleDesktopRegisterIndexingPlugin: IDispatch
  • RegisterIndexingPlugin: Must be invoked to register as an indexing component.
    • Arguments:
      • BSTR extension_handled: An extension on which this component wishes to receive notifications from the crawler. If no interest in handling extensions the parameter must be NULL.
    • Returns:
      • S_OK if successful.
      • E_EXTENSION_REGISTERED in case the extension conflicts with an existing registration.
      • Appropriate error on failure.
Crawler Notification Registration

As mentioned above a component can register with GD to handle files with a particular file extension (or a set of file extensions). If you do this registration, the GD crawler will notify your component whenever it encounters a file with the registered extension.

For example, a component can register to handle files with the extension .myc by specifying the extension as an argument to the RegisterIndexingPlugin method (see code template below).

Only one component at a time can be registered to handle a particular file extension. If another component has already registered with GD on this machine to handle your file extension, RegisterIndexingPlugin will return the error E_EXTENSION_REGISTERED. To register more than one extension call RegisterIndexingPlugin for each extension.

Component Registration Code Template

The following template demonstrates how an indexing component can register with Google Desktop and receives crawler notifications for .myc files. 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 indexing plugin"));
    arr_descr.SetAt(2, CComVariant(L"Description"));
    arr_descr.SetAt(3, CComVariant(L"Indexes .myc files"));
    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 action component.
    // This two step registration allows the same plug-in to implement multiple
    // components
    CComPtr<IGoogleDesktopRegisterIndexingPlugin> spRegistration;

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

    if (SUCCEEDED(hr)) {
      CComVariant var;
      var.Clear();
      hr = spRegistration->RegisterIndexingPlugin(CComBSTR(L"myc"));

      if (SUCCEEDED(hr)) {
        hr = spRegistrar->FinishComponentRegistration();
      }
    }

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);
  }

Creating and Sending Events

After a successful registration with GD, a component can use the CreateEvent method from the IGoogleDesktopEventFactory interface to create a GD event object based on any of the defined event schemas. Next, set the event object's properties via the AddProperty method from the IGoogleDesktopEvent interface. After setting all the relevant properties, use the Send method from the same interface to send the event object to GD.

Event Interfaces Summary

The following summarizes the interfaces and their methods. All method return values are of type HRESULT.

interface IGoogleDesktopEventFactory : IDispatch

  • Creates new event objects.
  • CreateEvent: Create a new GD event object based on a specified event schema.
    • Arguments:
      • BSTR component_guid_or_progid: The creating component's GUID. BSTR schema_name: Fully qualified name of the GD event schema that defines the event (e.g. Google.Desktop.IM, not just IM).
      • [out, retval] IDispatch **event: Pointer used to return the newly created event object.
    • Returns:
      • [out, retval] IDispatch **event Pointer to the newly created event object. S_OK on success. E_NO_SUCH_SCHEMA if an invalid schema_name value was given.
      • Otherwise, an appropriate error code
interface IGoogleDesktopEvent : IDispatch
  • Constants:
    • enum EventFlags
      • EventFlagIndexable: Sent to GD with all event objects to indicate an indexable event. Value 0x00000001.
      • EventFlagHistorical: Sent to GD when the event is historical (generated from a crawl over files or other past created data) rather than created as a real time response to a currently happening event. Value 0x00000010.

  • AddProperty: Adds a property-value pair to the event.
    • Arguments:
      • BSTR property_name: Name of the property, which must exist in the event schema or else an error will result.
      • VARIANT property_value: Value set for the property, which must be an appropriate type as defined in the event schema.
    • Returns:
      • S_OK if a success. E_NO_SUCH_PROPERTY if the value specified for property_name does not exist in the schema. Any error returned from VariantChangeType if the value type does not match the event schema specification.
      • Other appropriate error codes.

  • Send: Sends the event to GD. Once an event has been sent, you cannot resend it or add to or change its properties.
    • Arguments:
      • long event_flags: A bitwise OR of the relevant EventFlags enumeration values. See the code template below.
    • Returns:
      • S_OK if a success.
      • E_COMPONENT_DISABLED if this component has been disabled. A user can disable the component from their GD Preferences page (i.e. Don't index and store this data type). Also, GD may automatically disable a component if the component crashes too often.
      • S_INDEXING_PAUSED if the user has temporarily paused GD. While GD is paused, it does not accept any event objects.
      • E_EVENT_TOO_LARGE if the total size of the event object is too big, even after the content property has been truncated to 0, GD rejects the event object.
      • E_SERVICE_NOT_RUNNING if GD has been turned off and cannot accept event objects.
      • E_INVALID_EVENT_FLAGS if an event flag other than EventFlagIndexable or EventFlagHistorical was sent as an argument.
      • Otherwise, an appropriate error code.
Event Interfaces Code Template

The following template uses the fictional MyComponent, which deals with .myc text files. Variable names are prefaced by "mc" for "MyComponent".

  // Create an event factory object.
  CComPtr<IGoogleDesktopEventFactory> mcFactory;
  HRESULT hr = mcFactory.CoCreateInstance(CLSID_GoogleDesktop, 
                                          NULL, CLSCTX_INPROC);
  if (FAILED(hr))
    return hr;
      
  // Use the event factory to create an event object of the desired schema 
  // type. A pointer to the new event is returned via the final CreateEvent 
  // parameter.
  CComPtr<IDispatch> mcEventDisp;
  hr = mcFactory->CreateEvent(CComBSTR(CLSID_MyComponent),
                                 CComBSTR(L"Google.Desktop.TextFile"), 
                                 &mcEventDisp);
  if (FAILED(hr))
    return hr;

  CComQIPtr<IGoogleDesktopEvent> mcEvent(mcEventDisp);
  ATLASSERT(mcEventDisp && mcEvent);
  if (mcEvent == NULL)
    return hr;
      
  // Set the event object's properties.
  if (SUCCEEDED(hr))
    // mcFormatType is either "text/plain" or "text/html". This is required 
    // for all events.  
    hr = mcEvent->AddProperty(CComBSTR(L"format"), 
                                 CComVariant(mcFormatType));

  if (SUCCEEDED(hr))
  // mcContent is the indexable content from the file. 
  // This is required for all events.
    hr = mcEvent->AddProperty(CComBSTR(L"content"), CComVariant(mcContent));
      
  // Set other event properties...
      
  if(FAILED(hr))
    return hr;
      
  // If everything has worked so far, send the event object to GD, 
  // with the type of event flag argument(s).
  hr = mcEvent->Send(EventFlagIndexable);

  // If a historical event, do instead
  // hr = mcEvent->Send(EventFlagIndexable | EventFlagHistorical);
  if (FAILED(hr)) 
    // You may want to add code for handling the send()-specific error codes.
    return hr;

Handling GD Crawler Notifications

Components registered to receive crawler notifications from GD must implement the DGoogleDesktopFileNotify dispinterface. HandleFile is invoked when the crawler comes across a file registered to this component. The component is then responsible for instantiating the event factory and sending the appropriate event objects to GD.

Crawler Notification Handler Interface Summary

The following summarizes the interface and its method. The method returns an HRESULT.

dispinterface DGoogleDesktopFileNotify

  • HandleFile: Invoked when the GD crawler encounters a file with an extension registered to this component.
    • Arguments:
      • BSTR full_path_to_file: the file to handle.
      • IDispatch *event_factory: an event factory that will be used to create the event objects to send to the GD engine.
    • Returns:
      • S_OK if the file was handled.
      • Otherwise, an appropriate error. The crawler may do special handling for certain error values, such as retrying its indexing operation for HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), so components should be accurate when reporting errors. The crawler may also use any component returned error info object for logging and reporting purposes, so please do not skimp on error reporting through SetErrorInfo.
Crawler Notification Handler Code Template

The following template uses the fictional MyComponent, which deals with .myc text files. The prefix mc is used before variable names to make them MyComponent specific.

STDMETHODIMP MyComponent::HandleFile(BSTR full_path_to_file, IDispatch *event_factory) {

  // Event factory object to handle the passed in pointer from GD.
  CComPtr<IGoogleDesktopEventFactory> mcEventFactory;

  // Used to create an event object for this file to send back to GD.
  CComPtr<IDispatch> mcEventDisp;

  HRESULT hr;
 
  hr  = event_factory->QueryInterface(&mcEventFactory);  // Get the event factory
  if (FAILED(hr))
    return Error(L"No event factory", hr);

  // Replace "Google.Desktop.TextFile" with the appropriate schema for your file.
  hr = mcEventFactory->CreateEvent(CComBSTR(CLSID_MyComponent),
         CComBSTR(L"Google.Desktop.TextFile"), &mcEventDisp);
  if (FAILED(hr))
    return Error(L"Unable to create event", hr);
   
  CComQIPtr<IGoogleDesktopEvent> mcEvent(mcEventDisp);
 
  ATLASSERT(mcEventDisp && mcEvent);
  if (mcEvent == NULL)
    return Error(L"Event does not implement IGoogleDesktopEvent", E_UNEXPECTED);

  // Get indexable content from the file.
  // Set the event object's properties.
  // Send the event object to GD.

}

Writing and Distributing Your GD Plug-in

Developing a GD Plug-in With Visual Studio

You can use Visual Studio 2003 to create a class template for your plug-in, such that you only have to fill in registration with GD and, if necessary, how your HandleFile method is implemented.

The steps needed are:

  1. Launch Visual Studio 2003. Select File >New Project. Select ATL project.
    1. Give the project an appropriate name
    2. Click OK.
  2. Select the Application Settings tab.
    1. De-select Attributed, and leave all other settings alone.
    2. Click Finish.
  3. Your new project will open in a new solution. Right-click your project.
    1. From the Add submenu, select Add Class.
    2. From the resulting dialog, select ATL Simple Object.
    3. Click Open.
    4. Name your new class, for example MyCrawlPlugin.
    5. Select the Options tab.
    6. Select threading model Both.
    7. Check the checkbox next to ISupportErrorInfo to enable it.
    8. Click Finish.
  4. Your source file will open in Visual Studio.
  5. Go to Class View.
    1. Navigate to your main interface, for example IMyCrawlPlugin for your MyCrawlPlugin class.
    2. Right click, and from the Add submenu select Add Method.
    3. Add your HandleFile method, specifying both the BSTR and IDispatch arguments.
    4. Click Finish when done.

You now have a template for your class, so only GD registration and the implementation of the HandleFile method remains.

Distributing Your Plug-in

You should write your plug-in such that on user machines its code will be located in C:\Program Files\<Company Name>\<Plug-in name>.<extension>.

To submit your plug-in to Google for possible placement on the official GD plug-in download page, click the Submit Software link here or in this page's left-side menu. Fill out the form there, which includes an entry for uploading your code.

Back to top