October 12, 2008

Communicating with MS Communicator

Here are some code snippets to communicate with communicator.

Assuming MS communicator is already instantiated & running on your m/c

IMessengerContacts contactCollection;

private void GetCommunicatorContacts (){

CommunicatorAPI.MessengerClass communicatorObject = new CommunicatorAPI.MessengerClass();

IMessengerContactAdvanced contact = (IMessengerContactAdvanced)communicatorObject.GetContact(communicatorObject.MySigninName, communicatorObject.MyServiceId);

object[] presenceProperties = new object[8];

// presenceProperties[(int)PRESENCE_PROPERTY.PRESENCE_PROP_MSTATE] = (MISTATUS)status;
// contact.PresenceProperties = (object)presenceProperties;

contactCollection = (IMessengerContacts)communicatorObject.MyContacts;

//get collection of contacts for local client
if (contactCollection != null) {
//iterate over collection of contacts
foreach (IMessengerContact contactItem in contactCollection) {
//add contact to listview
createContactItem(contactItem);
}
}
}

public void createContactItem(object passedContact) {
/*
* called when a non-XP workstation is host of application. The contacts cannot be
* displayed under ListViewGroup objects. Instead, the contact collection of the
* communicator object is iterated on and each contact in the collection is loaded
* in the ListView with its presence properties.
*/

//cast passedContact to IMessengerContact interface
try {
IMessengerContactAdvanced workContact = (IMessengerContactAdvanced)passedContact;

Console.WriteLine(workContact.FriendlyName.ToString());

//create new ListViewItem object with contact Friendly Name
ListViewItem contactItem = new ListViewItem(workContact.FriendlyName.ToString());

//set presence icon and availability string
string statusString = updateContactList(
contactItem,
(IMessengerContactAdvanced)workContact
);
Console.WriteLine(statusString);
}
catch (Exception ex) { }
}

private string updateContactList(
ListViewItem contactItem,
IMessengerContactAdvanced contact
) {
/*
* this method updates the ListView item passed as parameter 1 with the status information
* of the passed IMessengerContact object
*/

string statusString = "";
switch (contact.Status) {
case MISTATUS.MISTATUS_AWAY:
statusString = "Away";
contactItem.ImageIndex = 1;
break;
case MISTATUS.MISTATUS_BE_RIGHT_BACK:
statusString = "Be right back";
contactItem.ImageIndex = 1;
break;
case MISTATUS.MISTATUS_BUSY:
statusString = "Busy";
contactItem.ImageIndex = 10;
break;
case MISTATUS.MISTATUS_DO_NOT_DISTURB:
statusString = "Do not disturb";
contactItem.ImageIndex = 8;
break;
case MISTATUS.MISTATUS_IN_A_CONFERENCE:
statusString = "In a conference";
contactItem.ImageIndex = 10;
break;
case MISTATUS.MISTATUS_IN_A_MEETING:
statusString = "In a meeting";
contactItem.ImageIndex = 10;
break;
case MISTATUS.MISTATUS_OFFLINE:
statusString = "Off-line";
contactItem.ImageIndex = 16;
break;
case MISTATUS.MISTATUS_ON_THE_PHONE:
statusString = "In a call";
contactItem.ImageIndex = 10;
break;
case MISTATUS.MISTATUS_ONLINE:
statusString = "Available";
contactItem.ImageIndex = 19;
break;
case MISTATUS.MISTATUS_IDLE:
statusString = "Idle";
contactItem.ImageIndex = 14;
break;
case MISTATUS.MISTATUS_OUT_OF_OFFICE:
statusString = "Out of the office";
contactItem.ImageIndex = 1;
break;
case MISTATUS.MISTATUS_OUT_TO_LUNCH:
statusString = "Out to lunch";
contactItem.ImageIndex = 1;
break;
default:
statusString = "Unknown";
contactItem.ImageIndex = 22;
break;
}

//The status string of the listview item is updated

//instantiate a collection of sub-items for the current listview item
ListViewItem.ListViewSubItemCollection subCollection = contactItem.SubItems;

//iterate over the collection, looking for the subitem whose name is "Status"
foreach (ListViewItem.ListViewSubItem subItem in subCollection) {
//if the "Status" item then update the text value
if (subItem.Name == "Status")
subItem.Text = statusString;
}
return statusString;
}





If MS communicator is not instantiated & not running on your m/c then use the following method to get activate communicator. Rest of the code to get contact is same as above.



private void CreateCnn() {
try {
MessengerClass communicator = null;

bool connected = false;
int parentHandle = 0;
string account = "myemail@comp.com";
string passwd = "pwd";
try {
communicator = new MessengerClass(); // here
communicator.Signin(parentHandle, account, passwd);
communicator.MyStatus = MISTATUS.MISTATUS_INVISIBLE;

}
catch (Exception E) {
if (communicator != null && parentHandle != 0)
communicator.Signout();
Console.WriteLine(E.Message.ToString());
}
}
catch (Exception AE) {
Console.WriteLine(AE.Message.ToString());
}
}

Some issues & solutions:

If communicator instance is not available & if you try to access then you get following error. Make sure you have logged in or use the last piece of code to activate communicator.

Creating an instance of the COM component with CLSID {8885370D-B33E-44B7-875D-28E403CF9270} from the IClassFactory failed due to the following error: 8007000e.

You get following exception if you try to create instance of communicator which is already created & signed-in.

Exception from HRESULT: 0x81000304