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 (11)

  1. n0oDLe says:

    I have OC2007 R2 up and running (verified in the registry value) but the error still shows up.

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

    what else can I try?

  2. cmayo says:

    @ n0oDLe.  I usually see this error when VS is running as Admin.  Run VS normally and it should work.

    Chris

  3. n0oDLe says:

    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.

  4. cmayo says:

    @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.

  5. n0oDLe says:

    Oh I see… well, thanks a lot for your help. I will research about this API 🙂

  6. Prashanth says:

    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.

  7. moh. Barakat says:

    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

  8. cmayo says:

    @moh – I've never seen this value stay at 2 when the user is signed out.  What version of Communicator are you using?  

  9. Megan says:

    Could you please re-add the link to the video? I am unable to access it.

  10. Lam says:

    Communicator is in running state is not enough. I realise that if the communicator in in signedout status, we cant create an instance of Messesenger. That means there must be 2 conditions, Communicator is running and already signed in if we want to create an instance of Messenger. The tricky thing is we cant check the status of the Communicator if we dont have an instance of the Messenger yet. Dont know how to deal with this yet.

  11. Lam says:

    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.