- UC 14 Metro - OCS 14/OC 14 platform early adopter program
-
"Metro" is the Microsoft Early Adopter Program for partners and customers that want to invest in our future platform technologies to get competitive advantage.
After our PDC09 sessions on Office Communications Server “14”, Office Communicator “14” and the new platform SDKs, I’ve been getting a lot of questions about getting access to the new bits.
UC “14” Metro is the program to get early access to these bits before they become publically available.
To join UC “14” Metro, you need to have a non-disclosure agreement with Microsoft and have a project scoped/planned for leveraging the UC “14” platform SDKs.
UC “14” Metro benefits include early access to the UC “14” products and platform SDKs to build your project, technical briefings on the platform, deep technical training and developer support.
To be considered for the program, talk to your Microsoft representative and let them know you’d like to be nominated for UC “14” Metro. If you don’t know who to ask, email details about your company and project to metroreq@microsoft.com, and we’ll put you in touch with the right person.
The program will start in January with technical briefing webcasts and training will start in the second quarter of next year.
Thanks,
Chris.
- PDC09: Microsoft Unified Communications: Developer Platform Futures on demand now
-
My PDC09 session Microsoft Unified Communications: Developer Platform Futures is now available as an on demand video.
Thanks,
Chris
- @PDC09: Meet me @ Ask the Experts
-
I’ve had some really great discussions around UC Wave 14 and UC development while here at the PDC09. If we haven’t managed to sit down and talk, meet me tonight in hall G from 5:30 pm to 7:00 pm.
I’ll see you there.
Thanks,
Chris.
- @PDC09: Free Programming for Unified Communications book @ UC booth
-
Come see us at the booth and we’ll give you a copy of the UC development book. We have a limited supply, so come by soon.
I’ll see you there.
Thanks,
Chris.
- @PDC09: Integrating and Extending OC 14 Session
-
Just waiting for the Day 2 Keynote to start. Remember to head over to David’s session on integrating OC 14 features into your WPF and Silverlight apps right after the keynote.
Integrating and Extending the Microsoft Office Communicator Experience with Windows Presentation Foundation and Microsoft Silverlight
David Ollason in 408A on Wednesday at 11:30 AM.
I’ll see you there.
Thanks,
Chris.
- @PDC09: Microsoft Unified Communications: Developer Platform Futures (PRO5)
-
Thanks to everyone that attended my PDC09 session today. I’ll link to the session recording when it’s posted on Ch. 9, but here’s a quick recap of what was covered:
- The UC “14” Wave will consist of Exchange 2010 (released last week at TechEd Europe), Office Communications Server “14”* and Office Communicator “14”*. With the release of those products we’ll also release a totally new client platform and a largely revamped server platform.
- The Office Communicator 14* platform SDKs will include:
- Office Communicator 14 Controls for WPF and Silverlight*: Allows you to integrate the OC 14 UI and features (presence, contact lists, contact info and communications) into your applications with very little code.
- Office Communicator 14 Managed API*: Exposes the OC 14 object model as a set of managed classes, providing you the ability to extend the client communications experience. You can use the API to send application data as conversation context and take action on that communication context on the receiving side by launching your application or extending the conversation window using Silverlight to display application data and features.
- The Office Communications Server 14* SDKs will include:
- Unified Communications Managed API 3.0 Workflow Activities: Exposes OCS 14 communications as a set of Windows Workflows Activities that execute on an incoming or outgoing call. The API supports IM, voice, presence and call control activities. Use this API to integrate OCS 14 communications into your business processes (from a SharePoint 2010 workflow, for example).
- Unified Communications Managed API 3.0 Core SDK: Provides a managed code object model API for the end to end communications stack for OCS 14. UCMA 3.0 will add programmatic access to the new OCS 14 features as well as streamlining many common server side development scenarios. Use this API to build sophisticated communication solutions like personal virtual assistants, web click to chat/click to call solutions, web service gateways, etc.
- The Exchange 2010 SDKs will include:
- Exchange Web Services: Provides a web services API for accessing data and business logic exposed by Exchange. Available now, details are here.
- Exchange Web Services Managed API 1.0: Provides a managed class library for EWS, making EWS development very discoverable and productive. Available now, details here.
I’ll provide more details over the common weeks. Exciting times ahead!
Thanks,
Chris.
*Not the final names.
- @PDC09: Please fill out your evals!!!
-
Everything is ready to go for my Microsoft Unified Communications: Developer Platform Futures (PRO5) session @ 11 AM tomorrow in 515B. I hope to see you there.
We always appreciate your feedback on sessions at PDC, so please fill out your evals. Your feedback has a real positive affect on future PDC sessions.
And, new this year, filling out your evals will have a positive impact on the Boys and Girls Club of Los Angeles. For every attendee who completes an eval, Microsoft will donate $1 to this worthwhile charity. For every attendee who completes 5 session evals, Microsoft will donate $2.
So please, fill out those evals!
Thanks,
Chris
- Unified Communications @ PDC09
-
I love the PDC. Before I joined Microsoft in 2000, I went to every PDC so I could evaluate the future of the Microsoft platform and integrate it into my development and architecture.
Since I joined the company, I’ve attended every PDC to share what we’re doing at Microsoft with regards to the future of the platform to start the conversation with other developers around feedback and early adoption.
From either side of the conversation, it’s always been worth getting out of the office.
Here are the 3 sessions we’ll have on the UC platform at PDC09:
Chris Mayo
Learn how Microsoft Communications Server and Microsoft Exchange provide a comprehensive and flexible communications platform for developers. Get a first look at the next generation of this platform through a series of demos and code examples. See how to embed Communicator features in your application using new Microsoft Silverlight and Windows Presentation Foundation (WPF) controls, and learn about the new API to develop full custom clients for Communications Server. Also see how the UC Managed API 3.0 provides access to the new Voice-over-IP features of Communication Server.
David Ollason
Come take an in-depth look at how to integrate and extend the Office Communicator experience into your Windows Presentation Foundation (WPF) and Silverlight applications. See how to provide the same integration experience as Office and Outlook including contact search, contact lists, presence, contact details and more. Learn how to pass contextual data from your application using the new contextual conversation API.
Jason Henderson
Learn how to make your application calendar or contact aware with the Exchange Web Services Managed API and Exchange Online. Get a first look at our new Exchange Web Services and Exchange Online developer story. See how developers can leverage the power of Azure and Exchange Web Services to create rich Software + Services solutions on Windows Presentation Foundation (WPF) or Microsoft Silverlight. Come learn how quick and easy it is to develop an Exchange Web Services application that can be deployed to millions of seats both on-premises and in the cloud.
When I’m not speaking or attending the other UC platform sessions, I’ll be in the Expo or at the evening events.
I hope to see you there.
Thanks,
Chris
- My Schedule at TechEd Europe 2009
-
I’ll be at TechEd Europe this year speaking on the future of the UC platform (OCS, OC, Exchange and Outlook) and meeting up with my European friends and colleagues.
I’m speaking at the following session:
UNC304 The State of the Art in Microsoft's Unified Communications Developer Platform (*PDC at TechEd)
Presenter: Chris Mayo
Tue 11/10 | 17:00-18:15 | Paris 1 - Hall 7-1c
Programmable Communications have become a reality over the last two years. Developers can now easily embed email, chat, and voice/video deeply into their software leveraging their .NET skills. This session gives an overview of the capabilities of the Microsoft Unified Communications platform and shows an in-depth code walk-through of key scenarios any developer can use in their software.
When I’m not in that session, I’ll be at the Expo in the UC booth and hanging out at the various evening events.
We’ve got over 60 sessions in the UC track this year for both developers and IT professionals (and those of us that do both). You can get details on the track here:
http://www.msteched.com/europe/public/sessionlist.aspx
I hope to see you there.
Thanks,
Chris
- Exchange 2010 and Exchange Web Services - What’s New Webcasts
-
Exchange Web Services gives you programmatic access to the information and business logic in Exchange 2010. If you think about all the stuff you do in Outlook 2007 to manage your daily life (mail to communicate with friends and coworkers, calendar items to manage your day and tasks to track the things that you need to get done), all that information and business logic (think free/busy when scheduling a meeting) is provided by Exchange and accessible via the Exchange Web Services Managed API.
This is a quick video with Jason Henderson and David Claux of the EWS team to show what you can do with the new EWS Managed API and what’s new in Exchange 2010 for developers.
Check out the following web casts to learn more.
10/13/2009 - Exchange Server 2010 Development (Part 1 of 6): Migrating Applications to Exchange Web Services
10/14/2009 - Exchange Server 2010 Development (Part 2 of 6): A Deep Dive into Using Autodiscover Service in Exchange Web Services
10/15/2009 - Exchange Server 2010 Development (Part 3 of 6): A Deep Dive into Impersonation and Delegation in Exchange Web Services
10/20/2009 - Exchange Server 2010 Development (Part 4 of 6): A Deep Dive into Exchange Web Services Notifications (Push/Pull)
10/21/2009 - Exchange Server 2010 Development (Part 5 of 6): A Deep Dive into the Exchange Web Services Managed API
10/22/2009 - Exchange Server 2010 Development (Part 6 of 6): Best Practices for Building Scalable Exchange Server Applications
Thanks,
Chris
- How to get presence using Office Communicator SDK
-
Displaying the presence information for the local user or their contacts is a common scenario when adding Unified Communications features to your client applications. For example, after Office Communicator is installed, Outlook 2007 displays the presence of contacts on the To: and the From: line so the user can make intelligent communication decisions (“should I reply in email or are there enough people online that a concall would be better?”) directly in Outlook 2007.
Luckily, it’s easy to integrate presence information into your client applications. This video shows a great example:
Let’s break down the code in the above video. When displaying presence information, you need to get the initial value to display and then update your client UI when changes to presence elements occur. In the code below, Messenger.GetContact() is used to get an instance of IMessengerContactAdvanced for displaying the initial presence information and the Messenger.OnMyStatusChange and Messenger.OnContactStatusChange events are used to get updated presence information:
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5:
6: using CommunicatorAPI;
7: using System.Runtime.InteropServices;
8:
9: namespace ContactPresence
10: {
11: class Program
12: {
13: private static Messenger _messenger;
14:
15: static void Main(string[] args)
16: {
17: _messenger = new Messenger();
18:
19: _messenger.OnContactStatusChange +=
20: new DMessengerEvents_OnContactStatusChangeEventHandler(
21: _messenger_OnContactStatusChange);
22: _messenger.OnMyStatusChange +=
23: new DMessengerEvents_OnMyStatusChangeEventHandler(
24: _messenger_OnMyStatusChange);
25:
26: IMessengerContactAdvanced localUser =
27: (IMessengerContactAdvanced)_messenger.GetContact(
28: _messenger.MySigninName, _messenger.MyServiceId);
29:
30: if (localUser != null)
31: {
32: DisplayContactPresence(localUser);
33: }
34:
35: Console.WriteLine("\nPress Enter key to exit the application.\n");
36: Console.ReadLine();
37:
38: _messenger.OnContactStatusChange -=
39: new DMessengerEvents_OnContactStatusChangeEventHandler(
40: _messenger_OnContactStatusChange);
41: _messenger.OnMyStatusChange -=
42: new DMessengerEvents_OnMyStatusChangeEventHandler(
43: _messenger_OnMyStatusChange);
44:
45: System.Runtime.InteropServices.Marshal.ReleaseComObject(_messenger);
46: _messenger = null;
47: System.Runtime.InteropServices.Marshal.ReleaseComObject(localUser);
48: localUser = null;
49: }
In order to display presence information, I’ve created a function called DisplayContactPresence. This function uses IMessengerContactAdvanced.PresenceProperties to access the presence for a contact (their status, availability, presence note, etc.). For example, the following code writes all the presence information for a contact out to the console:
1: static void DisplayContactPresence(IMessengerContactAdvanced contact)
2: {
3: object[] presenceProps = (object[])contact.PresenceProperties;
4:
5: if (contact.IsSelf)
6: {
7: Console.WriteLine("Local User Presence Info for {0}:",
8: contact.FriendlyName);
9: }
10: else
11: {
12: Console.WriteLine("Contact Presence Info for {0}:",
13: contact.FriendlyName);
14: }
15:
16: // Status or Machine State.
17: Console.WriteLine("\tStatus: {0}",
18: (MISTATUS)presenceProps[(int)PRESENCE_PROPERTY.PRESENCE_PROP_MSTATE]);
19: Console.WriteLine("\tStatus String: {0}",
20: GetStatusString((MISTATUS) presenceProps[(int)PRESENCE_PROPERTY.PRESENCE_PROP_MSTATE]));
21: // Status string if status is set to custom.
22: Console.WriteLine("\tCustom Status String: {0}",
23: presenceProps[(int)PRESENCE_PROPERTY.PRESENCE_PROP_CUSTOM_STATUS_STRING]);
24:
25: // Presence or User state.
26: Console.WriteLine("\tAvailability: {0}",
27: presenceProps[(int)PRESENCE_PROPERTY.PRESENCE_PROP_AVAILABILITY]);
28: Console.WriteLine("\tAvailability String: {0}",
29: GetAvailabilityString((int) presenceProps[(int)PRESENCE_PROPERTY.PRESENCE_PROP_AVAILABILITY]));
30:
31: // Presence note.
32: Console.WriteLine("\tPresence Note: \n'{0}'",
33: presenceProps[(int)PRESENCE_PROPERTY.PRESENCE_PROP_PRESENCE_NOTE]);
34: // Blocked status.
35: Console.WriteLine("\tIs Blocked: {0}",
36: presenceProps[(int)PRESENCE_PROPERTY.PRESENCE_PROP_IS_BLOCKED]);
37: // OOF message for contact, if specified.
38: Console.WriteLine("\tIs OOF: {0}",
39: presenceProps[(int)PRESENCE_PROPERTY.PRESENCE_PROP_IS_OOF]);
40: // Tooltip.
41: Console.WriteLine("\tTool Tip: \n'{0}'\n",
42: presenceProps[(int)PRESENCE_PROPERTY.PRESENCE_PROP_TOOL_TIP]);
43: }
44:
45: static string GetAvailabilityString(int availability)
46: {
47: switch (availability)
48: {
49: case 3000:
50: return "Available";
51: case 4500:
52: return "Inactive";
53: case 6000:
54: return "Busy";
55: case 7500:
56: return "Busy-Idle";
57: case 9000:
58: return "Do not disturb";
59: case 12000:
60: return "Be right back";
61: case 15000:
62: return "Away";
63: case 18000:
64: return "Offline";
65: default:
66: return "";
67: }
68: }
69:
70: static string GetStatusString(MISTATUS mStatus)
71: {
72: switch (mStatus)
73: {
74: case MISTATUS.MISTATUS_ALLOW_URGENT_INTERRUPTIONS:
75: return "Urgent interuptions only";
76: case MISTATUS.MISTATUS_AWAY:
77: return "Away";
78: case MISTATUS.MISTATUS_BE_RIGHT_BACK:
79: return "Be right back";
80: case MISTATUS.MISTATUS_BUSY:
81: return "Busy";
82: case MISTATUS.MISTATUS_DO_NOT_DISTURB:
83: return "Do no disturb";
84: case MISTATUS.MISTATUS_IDLE:
85: return "Idle";
86: case MISTATUS.MISTATUS_INVISIBLE:
87: return "Invisible";
88: case MISTATUS.MISTATUS_IN_A_CONFERENCE:
89: return "In a conference";
90: case MISTATUS.MISTATUS_IN_A_MEETING:
91: return "In a meeting";
92: case MISTATUS.MISTATUS_LOCAL_CONNECTING_TO_SERVER:
93: return "Connecting to server";
94: case MISTATUS.MISTATUS_LOCAL_DISCONNECTING_FROM_SERVER:
95: return "Disconnecting from server";
96: case MISTATUS.MISTATUS_LOCAL_FINDING_SERVER:
97: return "Finding server";
98: case MISTATUS.MISTATUS_LOCAL_SYNCHRONIZING_WITH_SERVER:
99: return "Synchronizing with server";
100: case MISTATUS.MISTATUS_MAY_BE_AVAILABLE:
101: return "Inactive";
102: case MISTATUS.MISTATUS_OFFLINE:
103: return "Offline";
104: case MISTATUS.MISTATUS_ONLINE:
105: return "Online";
106: case MISTATUS.MISTATUS_ON_THE_PHONE:
107: return "In a call";
108: case MISTATUS.MISTATUS_OUT_OF_OFFICE:
109: return "Out of office";
110: case MISTATUS.MISTATUS_OUT_TO_LUNCH:
111: return "Out to lunch";
112: case MISTATUS.MISTATUS_UNKNOWN:
113: return "Unknown";
114: default:
115: return string.Empty;
116: }
117: }
When the presence of the local user or any of their contacts changes, the Messenger.OnMyStatusChange and Messenger.OnContactStatusChange events fire, respectively:
1: static void _messenger_OnMyStatusChange(int hr, MISTATUS mMyStatus)
2: {
3: // Your code to work with presence goes here...
4: Console.WriteLine("\n***OnMyStatusChange***");
5:
6: DisplayContactPresence((IMessengerContactAdvanced)
7: _messenger.GetContact(_messenger.MySigninName, _messenger.MyServiceId));
8: }
9:
10: static void _messenger_OnContactStatusChange(object pMContact, MISTATUS mStatus)
11: {
12: // Your code to work with presence goes here...
13: Console.WriteLine("\n***OnContactStatusChange***");
14:
15: DisplayContactPresence((IMessengerContactAdvanced) pMContact);
16: }
One thing to note, both events have a MISTATUS value passed to provide the current status of the contact. Using IMessengerContactAdvanced.PresenceProperties is preferred to using this value since it provides access to all the presence information for a contact, not just status.
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.
You can download the WPF Presence Controls for Office Communicator 2007 example used in the first demo to see how this code is used in a solution.
More details, tips and tricks on UC development can be found in the Programming for Unified Communications book.
Thanks,
Chris
- How to save IM conversations using Office Communicator SDK
-
Archiving the contents of an IM conversation using the Office Communicator SDK is something that I get asked about pretty routinely. For example, let’s say that you want to launch an IM call from your application using the OC SDK and archive that conversation to be retrieved later (displaying all the application specific conversations in your application or on a SharePoint site, etc.).
The OC SDK provides the IMessengerConversationWndAdvanced.History property to access the body of an IM conversation. For example, the following console application launches an IM call and then writes out the IM history to the console:
1: namespace History
2: {
3: class Program
4: {
5: private static Messenger _messenger;
6: private static IMessengerAdvanced _messengerAdv;
7:
8: private static long _myConvHWND = 0;
9: private static IMessengerConversationWndAdvanced _myConv;
10:
11: static void Main(string[] args)
12: {
13: _messenger = new Messenger();
14: _messengerAdv = (IMessengerAdvanced)_messenger;
15:
16: _messenger.OnIMWindowCreated +=
17: new DMessengerEvents_OnIMWindowCreatedEventHandler(
18: _messenger_OnIMWindowCreated);
19: _messenger.OnIMWindowDestroyed +=
20: new DMessengerEvents_OnIMWindowDestroyedEventHandler(
21: _messenger_OnIMWindowDestroyed);
22:
23: object[] sipUris = new object[] { "kf@fabrikam.com", "cb@fabrikam.com" };
24:
25: object obj = _messengerAdv.StartConversation(
26: // The call media.
27: CONVERSATION_TYPE.CONVERSATION_TYPE_IM,
28: // The participants.
29: sipUris,
30: // Not supported.
31: null,
32: // The conversation window title as as string.
33: "Account: Johnson (ID:12345)",
34: // Not supported. Pass "1".
35: "1",
36: // Not supported.
37: null);
38:
39: _myConvHWND = long.Parse(obj.ToString());
40:
41: Console.WriteLine(
42: "Press the Enter key to see IM conversation History.");
43: Console.ReadLine();
44:
45: if (_myConv != null)
46: {
47: try
48: {
49: Console.WriteLine(_myConv.History);
50: }
51: catch (COMException ce)
52: {
53: Console.WriteLine(
54: "COM Exception " + ce.ErrorCode.ToString());
55: }
56: }
57:
58: Console.WriteLine("Press the Enter key to exit the application.");
59: Console.ReadLine();
60:
61: _messenger.OnIMWindowCreated -=
62: new DMessengerEvents_OnIMWindowCreatedEventHandler(
63: _messenger_OnIMWindowCreated);
64: _messenger.OnIMWindowDestroyed -=
65: new DMessengerEvents_OnIMWindowDestroyedEventHandler(
66: _messenger_OnIMWindowDestroyed);
67:
68: Marshal.ReleaseComObject(_messenger);
69: _messenger = null;
70: Marshal.ReleaseComObject(_messengerAdv);
71: _messengerAdv = null;
72:
73: if (_myConv != null)
74: {
75: Marshal.ReleaseComObject(_myConv);
76: _myConv = null;
77: }
78: }
In the code above, I’m registering for the OnIMWindowCreated and OnIMWindowDestroyed events to get and release my reference to the conversation window (_myConv) so I can access the History property. The code below shows how I manage the _myConv reference:
1: static void _messenger_OnIMWindowCreated(object pIMWindow)
2: {
3: IMessengerConversationWndAdvanced newConv =
4: (IMessengerConversationWndAdvanced)pIMWindow;
5:
6: if (newConv.HWND == _myConvHWND)
7: {
8: newConv.SendText("This is a ongoing conversation " +
9: "about the Account: Johnson (ID:12345) " +
10: "and will be saved on the account site.");
11:
12: _myConv = newConv;
13: }
14: }
15:
16: static void _messenger_OnIMWindowDestroyed(object pIMWindow)
17: {
18: if (object.ReferenceEquals((object)_myConv, pIMWindow))
19: {
20: Marshal.ReleaseComObject(_myConv);
21: _myConv = null;
22: }
23: }
In OnIMWindowCreated, I set _myConv using the pIMWindow object passed as an event argument after confirming it’s the conversation I started in code (by comparing the HWNDs). When OnIMWindowDestroyed fires, I check to make sure the window being destroyed is mine by using object.ReferenceEquals and release the reference. Note that I can’t use the HWND property in OnIMWindowDestroyed since conversation window no longer exists and _myConv is no longer a valid reference.
While this code works, it’s not an ideal solution. I can’t rely on the user to do something (click a button, etc.) in my app before the conversation is closed. I’d rather just write the IM conversation history out when the conversation is completed. This leads a lot of developers to try the following:
1: static void _messenger_OnIMWindowDestroyed(object pIMWindow)
2: {
3: if (object.ReferenceEquals((object)_myConv, pIMWindow))
4: {
5: Console.WriteLine(_myConv.History);
6:
7: Marshal.ReleaseComObject(_myConv);
8: _myConv = null;
9: }
10: }
But, the call to IMessengerConversationWndAdvanced.History throws an exception since _myConv is no longer a valid reference when OnIMWindowDestroyed fires.
Another solution I’ve seen is polling History on another thread through the life of the conversation and writing out the last value when the conversation window is destroyed. While this works, it’s less than ideal due to the resource you consume.
So what does provide a good working scenario? Creating a UCMA 2.0 IM robot that archives conversations and inviting that bot to all the conversations you want archived is a great solution (and a great future blog post).
Details on how to start conversations using the Office Communicator SDK can be found in the How to make calls via Office Communicator SDK and How to send IM text using Office Communicator SDK posts on this blog.
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
- How to send IM text using Office Communicator SDK
-
When starting call from your application using the Office Communicator Automation API, it’s often helpful to send some IM text to provide some context for the call (often using data from your application). For example, Outlook 2007 does this when you start a conversation using the IM and Call features from an email.
When the call is placed, Outlook 2007 uses the OC API to set the conversation window title and to provide details on the subject of the call (the email) via IM.
Here is a quick video that shows how to send IM text using the Office Communicator Automation API:
Let’s break down some of the details from the video. First, the IMessengerAdvanced.StartConversation() method is used to start the call. Once the call is accepted by the callee, a conversation window is created that I can use to send IM as part of the call. Due to the asynchronous nature of the OC API, this conversation window doesn’t get created right away. Luckily, the StartConversation() method returns the HWND of the conversation window so I can identify it in code when it is created. Registering for the OnIMWindowCreated event will give me access the conversation window when that happens. For example, the following code registers for the OnIMWindowCreated event, starts a new audio call and stores the HWND of conversation window to be created in a local variable _myConvHWND:
1: namespace StartConversation
2: {
3: class Program
4: {
5: private static Messenger _messenger;
6: private static IMessengerAdvanced _messengerAdv;
7:
8: private static long _myConvHWND = 0;
9:
10: static void Main(string[] args)
11: {
12: _messenger = new Messenger();
13: _messengerAdv = (IMessengerAdvanced)_messenger;
14:
15: _messenger.OnIMWindowCreated += new DMessengerEvents_OnIMWindowCreatedEventHandler(_messenger_OnIMWindowCreated);
16:
17: object[] sipUris = new object[] { "kf@fabrikam.com" };
18:
19: object obj = _messengerAdv.StartConversation(
20: // The call media.
21: CONVERSATION_TYPE.CONVERSATION_TYPE_AUDIO,
22: // The participants.
23: sipUris,
24: // Not supported.
25: null,
26: // The conversation window title as as string.
27: "My Audio Call with IM as Context",
28: // Not supported. Pass "1".
29: "1",
30: // Not supported.
31: null);
32:
33: _myConvHWND = long.Parse(obj.ToString());
34:
35: Console.WriteLine("Press the Enter key to exit the application.");
36: Console.ReadLine();
37:
38: _messenger.OnIMWindowCreated -= new DMessengerEvents_OnIMWindowCreatedEventHandler(_messenger_OnIMWindowCreated);
39:
40: Marshal.ReleaseComObject(_messenger);
41: _messenger = null;
42: Marshal.ReleaseComObject(_messengerAdv);
43: _messengerAdv = null;
44: }
When OnIMWindowCreated fires, it passes a reference to the conversation window via the IMessengerConversationWindowAdvanced interface. I can use the HWND property on this interface to see if the conversation is the one I created with StartConversation() and send some IM using the SendText() method. I need to check the HWND since OnIMWindowCreated will fire for every new conversation windows created by OC 2007 R2 (incoming or outgoing). For example:
1: static void _messenger_OnIMWindowCreated(object pIMWindow)
2: {
3: IMessengerConversationWndAdvanced newConv = (IMessengerConversationWndAdvanced)pIMWindow;
4:
5: if (newConv.HWND == _myConvHWND)
6: {
7: newConv.SendText("This IM was sent via SendText()...");
8: }
9: }
Using the SendText() method to provide some application data in the IM channel is a great way to add value to the calls you launch from your application. Using the Outlook 2007/Office Communicator 2007 R2 integration as an example, you can start to think of ways that you can provide context to the calls your application launches using data from your application.
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
- How to make calls via Office Communicator SDK
-
Starting Office Communicator calls from your code is one of the simplest and most powerful features you can add to your application using the Office Communicator Automation API.
This video shows some examples of the types of calls you can start in your code:
Let’s dive into the code. When making calls via the Office Communicator Automation API you call the IMessengerAdvanced.StartConversation() method and specify the participants, the media type (IM, audio, video) and any call specific information (such as the conversation window title). You get a reference to the IMessengerAdvanced interface by casting an instance of Messenger class.
For example, the following console application code starts an IM call with a single contact (kf@fabrikam.com) and sets the title of the conversation window to “My IM Call”:
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5:
6: using CommunicatorAPI;
7: using System.Runtime.InteropServices;
8:
9: namespace StartConversation
10: {
11: class Program
12: {
13: private static Messenger _messenger;
14: private static IMessengerAdvanced _messengerAdv;
15:
16: static void Main(string[] args)
17: {
18: _messenger = new Messenger();
19: _messengerAdv = (IMessengerAdvanced)_messenger;
20:
21: object[] sipUris = new object[] { "kf@fabrikam.com" };
22:
23: _messengerAdv.StartConversation(
24: // The call media.
25: CONVERSATION_TYPE.CONVERSATION_TYPE_IM,
26: // The participants.
27: sipUris,
28: // Not supported.
29: null,
30: // The conversation window title as as string.
31: "My IM Call",
32: // Not supported. Pass "1".
33: "1",
34: // Not supported.
35: null);
36:
37: Console.WriteLine("Press the Enter key to exit the application.");
38: Console.ReadLine();
39:
40: Marshal.ReleaseComObject(_messenger);
41: _messenger = null;
42: Marshal.ReleaseComObject(_messengerAdv);
43: _messengerAdv = null;
44: }
45: }
46: }
Changing the call media is just a matter of passing a different value from the CONVERSATION_TYPE enum. For example, the follow code starts an audio call:
1: _messengerAdv.StartConversation(
2: // The call media.
3: CONVERSATION_TYPE.CONVERSATION_TYPE_AUDIO,
4: // The participants.
5: sipUris,
6: // Not supported.
7: null,
8: // The conversation window title as as string.
9: "My Audio Call",
10: // Not supported. Pass "1".
11: "1",
12: // Not supported.
13: null);
Starting a conference is just a matter of starting a call with multiple participants. For example, the following code starts a video conference:
1: object[] sipUris = new object[] { "kf@fabrikam.com", "cb@fabrikam.com" };
2:
3: _messengerAdv.StartConversation(
4: // The call media.
5: CONVERSATION_TYPE.CONVERSATION_TYPE_VIDEO,
6: // The participants.
7: sipUris,
8: // Not supported.
9: null,
10: // The conversation window title as as string.
11: "My Video Conference",
12: // Not supported. Pass "1".
13: "1",
14: // Not supported.
15: null);
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
- Exchange 2010 RC available now
-
Details can be found at the Exchange Team Blog.
Thanks,
Chris