最近在專案上遇到一個問題,需要能夠在程式中獲取Lync會議的連結地址。Lync是微軟出品的一套即時通訊(IM)客戶端軟體,配合Microsoft Lync Server使用,其前身是Microsoft Office Communicator(MOC)。與Live Messenger相比,Lync更適合企業內部使用,因為它還具備一定的與企業級應用元件進行整合的功能。在Microsoft Office 2010/2013中,Lync已成為Office中的一個套件。
在企業內部使用Outlook和Lync的讀者一定知道,Outlook中有一個Lync的外掛,當啟用了該外掛後,即可在“日曆”檢視中通過單擊New Lync Meeting按鈕來安排一個帶有Lync線上會議連結地址的Appointment:
正如上圖所示,在這個Appointment視窗中,有個Join Lync Meeting的超級連結,滑鼠移動到這個連結上,會提示出其所對應的超級連結地址,也就是Lync線上會議的連結地址。現在,我們就需要通過編寫C#程式的方式,來獲得這個Lync線上會議的連結地址。
SDK的選擇
經過上網搜尋研究,與Outlook和Lync相關的SDK大致有以下幾種:
- Lync 2010/2013 SDK
- Exchange Web Services (EWS)
- Unified Communications Managed API (UCMA)
- Unified Communications Web API (UCWA)
Lync 2010/2013 SDK主要是通過Automation物件來實現Lync客戶端的操作,因此,使用Lync SDK時,Lync客戶端需要一直執行,否則無法獲得Automation物件。Lync SDK也支援Suppress UI的模式,這樣開發者就可以遮蔽Lync的使用者介面,而使用自己的軟體介面來使用Lync客戶端的功能,但無論是否是Suppress UI的模式,都需要Lync客戶端一直執行。
Exchange Web Services (EWS)是一套訪問Exchange Server的API,通過使用EWS,可以在程式中通過Exchange Server傳送電子郵件、管理電子郵件、安排Outlook會議,以及管理自己的Outlook資料夾等等。
Unified Communications Managed API (UCMA) 是一套基於.NET的API,通過使用UCWA,可以獲得Microsoft Lync Server的增強狀態資訊、即時訊息、電話、視訊、音訊、會議等的訪問和控制功能。
Unified Communications Web API (UCWA) 是UCMA的Web版,通過Javascript、Json等技術向異構平臺提供UCMA的功能。
終上所述,在我們的應用中,應該選擇Unified Communications Managed API (UCMA)來實現Lync線上會議連結地址的獲取。
程式碼實現
首先需要安裝Unified Communications Web API,這可以到微軟的官方網站下載。下載安裝之後,即可開始編寫程式碼。
建立一個控制檯應用程式(Console Application),新增對Microsoft.Rtc.Collaboration.dll程式集的引用。之後,還需要會議組織者在企業中的電子郵件地址,以及Lync伺服器的地址。前者容易獲得,讀者可以使用自己的郵件地址進行測試;而Lync伺服器的地址,則可以在托盤中右鍵單擊Lync圖示,在彈出的選單中選擇顯示Lync詳細資訊的選項來獲得。
下面的程式碼完整地展示了通過UCMA來獲取Lync線上會議的連結地址,具體內容請參考程式碼中的註釋:
using System; using System.Threading; using Microsoft.Rtc.Collaboration; using Microsoft.Rtc.Collaboration.ConferenceManagement; using Microsoft.Rtc.Signaling; namespace ConsoleApplication7 { class Program { static AutoResetEvent platformStartupCompleted = new AutoResetEvent(false); static AutoResetEvent endpointInitCompleted = new AutoResetEvent(false); static AutoResetEvent conferenceScheduleCompleted = new AutoResetEvent(false); static void Main(string[] args) { var ownerURI = "<在此填寫會議組織者URI,格式為:sip:郵箱地址>"; var serverAddress = "<在此填寫Lync伺服器地址>"; var applicationName = "ConsoleApplication"; // 通過ClientPlatformSettings來初始化一個CollaborationPlatform。 // 注意,Transport Type應使用SipTransportType.Tls。 ClientPlatformSettings clientPlatformSettings = new ClientPlatformSettings(applicationName, SipTransportType.Tls); CollaborationPlatform platform = new CollaborationPlatform(clientPlatformSettings); // 啟動CollaborationPlatform例項 platform.BeginStartup(platformEndStartup, platform); platformStartupCompleted.WaitOne(); Console.WriteLine("Platform initialized..."); // 通過UserEndpointSettings來初始化一個UserEndpoint。 UserEndpointSettings userEndpointSettings = new UserEndpointSettings(ownerURI, serverAddress); userEndpointSettings.Credential = System.Net.CredentialCache.DefaultNetworkCredentials; UserEndpoint endpoint = new UserEndpoint(platform, userEndpointSettings); // 建立UserEndpoint的連線 endpoint.BeginEstablish(endpointEndEstablish, endpoint); endpointInitCompleted.WaitOne(); Console.WriteLine("Endpoint initialized..."); // 設定會議的建立選項,詳細的設定選項請參考ConferenceScheduleInformation類的定義。 ConferenceScheduleInformation conferenceScheduleInformation = new ConferenceScheduleInformation(); conferenceScheduleInformation.AccessLevel = ConferenceAccessLevel.Invited; conferenceScheduleInformation.Description = "Conference Description"; ConferenceParticipantInformation participantA_Information = new ConferenceParticipantInformation(ownerURI, ConferencingRole.Leader); conferenceScheduleInformation.Participants.Add(participantA_Information); conferenceScheduleInformation.LobbyBypass = LobbyBypass.EnabledForGatewayParticipants; conferenceScheduleInformation.AutomaticLeaderAssignment = AutomaticLeaderAssignment.SameEnterprise; ConferenceMcuInformation audioVideoMCU = new ConferenceMcuInformation(McuType.AudioVideo); conferenceScheduleInformation.Mcus.Add(audioVideoMCU); // 根據會議的建立選項建立新的Lync會議 endpoint.ConferenceServices.BeginScheduleConference(conferenceScheduleInformation, conferenceEndScheduled, endpoint.ConferenceServices); conferenceScheduleCompleted.WaitOne(); Console.WriteLine("Press anykey to exit."); Console.ReadLine(); } static void conferenceEndScheduled(IAsyncResult ar) { try { ConferenceServices session = (ConferenceServices)ar.AsyncState; Conference conference = session.EndScheduleConference(ar); // 在控制檯輸出Lync會議的連結地址 Console.WriteLine(conference.WebUrl); } catch { throw; } finally { conferenceScheduleCompleted.Set(); } } static void endpointEndEstablish(IAsyncResult ar) { try { UserEndpoint endpoint = ar.AsyncState as UserEndpoint; endpoint.EndEstablish(ar); } catch { throw; } finally { endpointInitCompleted.Set(); } } static void platformEndStartup(IAsyncResult ar) { try { CollaborationPlatform collabPlatform = ar.AsyncState as CollaborationPlatform; collabPlatform.EndStartup(ar); } catch { throw; } finally { platformStartupCompleted.Set(); } } } }
執行效果
以下是本程式執行的結果,可以看到,程式已經可以在控制檯輸出會議連結地址了: