Getting sign in/sign out status via Office Communicator 2007 SDK

When using the Office Communicator 2007 SDK, you need to make sure that OC is running and signed in before you use classes from the SDK.  I often get email from developers new to the OC SDK who are getting errors when they try to debug their first applications.  For example, if OC 2007 R2 is not running on the client machine, you’ll get the following COMException when you try to create a instance of the Messenger class:

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

Or, if Office Communicator is running but the user has not signed in, you’ll get the following error trying to access your instance of the Messenger class:

“Exception from HRESULT: 0x8100031E” (an error code that translates to not logged on if you refer to the OC SDK documentation).

So, how do you make sure OC 2007 R2 is running and signed in before you enable your OC SDK features (and disable them when that status changes)? 

This video shows as example of this in a simple console application:

Chris – Added video.

To see if Office Communicator is running, read the HKEY_CURRENT_USER\Software\IM Providers\Communicator\UpAndRunning value via code:

    1:          static bool IsCommunicatorRunning()
    2:          {
    3:              return Convert.ToInt32(Microsoft.Win32.Registry.CurrentUser
    4:                              .OpenSubKey("Software").OpenSubKey("IM Providers")
    5:                              .OpenSubKey("Communicator").GetValue("UpAndRunning", 1)) == 2;
    6:          }

If this registry value is 2, OC is up and running and you’re able to create instances of Messenger class.  Messenger class can be used to wire up events to track changes to Office Communicator or the sign in status of the local user and query the initial sign in status of the local user.  For example, the following code does just that:

    1:          private static Messenger _messenger;
    2:          private static bool _signedIn = false;
    3:   
    4:          static void Main(string[] args)
    5:          {
    6:              if (IsCommunicatorRunning())
    7:              {
    8:                  _messenger = new Messenger();
    9:   
   10:                  _messenger.OnAppShutdown += new DMessengerEvents_OnAppShutdownEventHandler(_messenger_OnAppShutdown);
   11:                  _messenger.OnSignin += new DMessengerEvents_OnSigninEventHandler(_messenger_OnSignin);
   12:                  _messenger.OnSignout += new DMessengerEvents_OnSignoutEventHandler(_messenger_OnSignout);
   13:   
   14:                  if ((_messenger.MyStatus & MISTATUS.MISTATUS_ONLINE) == MISTATUS.MISTATUS_ONLINE)
   15:                  {
   16:                      _signedIn = true;
   17:                  }
   18:                  else
   19:                  {
   20:                      _signedIn = false;
   21:                  }
   22:   
   23:                  Console.WriteLine("\nPress Enter key to exit the application.\n");
   24:                  Console.ReadLine();
   25:   
   26:                  _messenger.OnAppShutdown -= new DMessengerEvents_OnAppShutdownEventHandler(_messenger_OnAppShutdown);
   27:                  _messenger.OnSignin -= new DMessengerEvents_OnSigninEventHandler(_messenger_OnSignin);
   28:                  _messenger.OnSignout -= new DMessengerEvents_OnSignoutEventHandler(_messenger_OnSignout);
   29:   
   30:                  Marshal.ReleaseComObject(_messenger);
   31:                  _messenger = null;
   32:              }
   33:          }

The following line sets the initial value of the _signedIn by using Messenger.MyStatus and the & operator, evaluating to true if the local user is in any of the online states (any value other than Offline or Unknown including Online, In a Call, etc.):

    1:                  if ((_messenger.MyStatus & MISTATUS.MISTATUS_ONLINE) == MISTATUS.MISTATUS_ONLINE)

The _signedIn value is kept up to date via the Messenger class events for signed in status:

    1:          static void _messenger_OnSignout()
    2:          {
    3:              _signedIn = false;
    4:          }
    5:   
    6:          static void _messenger_OnSignin(int hr)
    7:          {
    8:              if (hr == 0)
    9:              {
   10:                  _signedIn = true;
   11:              }
   12:          }
   13:   
   14:          static void _messenger_OnAppShutdown()
   15:          {
   16:          }

Note: OnSignOut will always fire before OnAppShutdown, so setting _signedIn to false during OnSignOut is enough to keep your application up to date.

If you’d like to try this code out for yourself, you’ll need to download the Office Communicator 2007 SDK and setup a UC development environment.

More details, tips and tricks on UC development can be found in the Programming for Unified Communications book. 

 

Thanks,

Chris

Comments

  • Anonymous
    March 03, 2010
    The comment has been removed

  • Anonymous
    March 04, 2010
    @ n0oDLe.  I usually see this error when VS is running as Admin.  Run VS normally and it should work. Chris

  • Anonymous
    March 05, 2010
    Chris, thanks a lot for your reply. When I run the web application using VS (with admin rights) it works but when I publish the application on IIS and browse the website, the error occurs. I'v already verified the COM Settings and looks good. (at least, the properties are the same on both development and production machines) thanks a lot for your help.

  • Anonymous
    March 07, 2010
    @n0oDLe - I see.  The OC SDK is not intended for web/server scenarios and isn't supported in these scenarios (it COM automates OC).  For what you want to do you need UCMA 2.0 and to crate a WCF/REST/RIA/etc. gateway to get presence.

  • Anonymous
    March 08, 2010
    Oh I see... well, thanks a lot for your help. I will research about this API :)

  • Anonymous
    May 04, 2010
    While creating an instance of the application from communicator custom tab-xbap page,  Iam Getting "retriving the com Clas factory componet with CLSID{8885370D-B33E-44B7-875D-28E403CF9270} failed due to the following error:80080005". Can you please let me know why this error come and please let me know if any fix/solution for the same.

  • Anonymous
    June 15, 2010
    Hi, the registry key value is always 2 even if client signed out from OCS. how to check if the user is signed out and the process is still running. I need to catch this situation (user is running his OCS application but not signed in). the value in this situation is 2 and if the user is signed in also the value is 2. can you help in this? thanksa lot

  • Anonymous
    June 20, 2010
    @moh - I've never seen this value stay at 2 when the user is signed out.  What version of Communicator are you using?  

  • Anonymous
    June 24, 2010
    Could you please re-add the link to the video? I am unable to access it.

  • Anonymous
    December 07, 2010
    The comment has been removed

  • Anonymous
    December 07, 2010
    Chris, I have the value of 2 for the AttendantConsole (Office Communications Server 2007 R2) when its not signed in. I have checked the Communicator 2007 also. The same thing happens.