共用方式為


整合 IM 應用程式與 Office

本文說明如何 (IM) 用戶端應用程式設定立即訊息,使其與 Office 2013、Office 2016、Office 2019 和 Office 365 中的社交功能整合,包括顯示目前狀態,以及從聯繫人卡片傳送立即訊息。

簡介

Office 2013 (和更新版本) 提供與 IM 用戶端應用程式的豐富整合,包括 Lync 2013 和 Teams。 這項整合為使用者提供來自 Word、Excel、PowerPoint、Outlook、Visio、Project 和 OneNote 內的 IM 功能,以及在 SharePoint 頁面上提供目前狀態整合。 用戶可以在聯繫人清單中看到人員的相片、名稱、目前狀態和聯繫人數據。 他們可以直接從聯繫人卡片啟動 IM 會話、視訊通話或電話, (Office 中呈現聯繫人資訊和通訊選項) 的 UI 元素。 Office 可讓您輕鬆地與聯繫人保持聯繫,而不需要將您帶出電子郵件或檔。

注意事項

本文使用 IM 用戶端應用程式一詞來特別參照安裝在用戶電腦上與 IM 服務通訊的應用程式。 例如,Lync 2013 和 Teams 會被視為 IM 用戶端應用程式。 本文不提供 IM 用戶端應用程式如何與 IM 服務通訊或 IM 服務本身的詳細資料。

您可以自定義 IM 用戶端應用程式,使其與 Office 通訊。 具體而言,您可以修改 IM 應用程式,使其在 Office UI 中顯示下列資訊:

  • 聯繫人相片。

  • 聯繫人名稱。

  • 聯繫人個人狀態注意事項。

  • 聯繫人狀態。

  • 聯繫人可用性字串 (例如「可用」或「不在辦公室」) 。

  • 聯繫人功能字串 (例如「視訊就緒」) 。

  • 按兩下 [IM 啟動]。

  • 單鍵視訊通話啟動。

  • 單鍵通話啟動 (包括 SIP、電話號碼、語音信箱,以及新號碼) 。

  • 連絡管理 (新增至IM群組) 。

  • 聯繫人位置和時區。

  • 聯繫人數據、電話號碼、電子郵件地址、職稱和公司名稱。

圖 1: Office 2013 中的聯繫人卡片

Office 2013 中的 人員 卡 Office

若要啟用與 Office 的整合,IM 用戶端應用程式必須實作 Office 提供的一組介面來連線。 此整合的 API 會包含在包含在 Microsoft.Office.UC.dll 檔案中的 UCCollborationLib 命名空間中,該命名空間隨包含 Lync / 商務用 Skype 的 Office 2013 版本一起安裝。 UCCollaborationLib 命名空間包含您必須實作才能與 Office 整合的介面。

重要事項

必要介面的類型庫內嵌在 Lync 2013/商務用 Skype 中。 對於第三方整合者而言,只有當目標計算機上同時安裝 Lync 2013 和 商務用 Skype 時,才能運作。 如果您要使用 Office 標準版 進行整合,則必須擷取類型庫,並將其安裝在目標計算機上。 Lync 2013 SDK 包含 Microsoft.Office.UC.dll 檔案。

注意事項

少數 Office 2010 應用程式可以與第三方 IM 提供者應用程式類似的整合:Outlook 2010、Word 2010、Excel 2010、PowerPoint 2010 和 SharePoint Server 2010 (使用 ActiveX 控件) 。 與 Office 2013 整合所需的許多步驟也適用於 Office 2010。 Office 2010 與 IM 提供者應用程式整合的方式有幾個主要差異:

  • Office 2010 不會顯示聯繫人的相片。
  • 您必須從 Office 2010 個別下載 Microsoft.Office.Uc.dll 檔案。 Lync 2010 SDK 包含 Office 2010 的 Microsoft.Office.UC.dll 檔案。
  • 當 Office 應用程式在 IM 用戶端應用程式上呼叫 IUCOfficeIntegration.GetAuthenticationInfo 方法時,它會傳入字元串 “14.0.0.0”。
  • Office 2010 會在連線到 IM 用戶端應用程式時,立即列舉所有群組和聯繫人。

Office 如何與 IM 用戶端應用程式整合

當 Office 2013 (或更新版本) 應用程式啟動時,它會經歷下列程式來與預設 IM 用戶端應用程式整合:

  1. 它會檢查登錄以探索預設 IM 用戶端應用程式,然後連線到它。

  2. 它會向 IM 用戶端應用程式進行驗證。

  3. 它會連線到 IM 用戶端應用程式所公開的特定介面。

  4. 它會決定目前登入使用者 (本機使用者) 的功能,包括取得用戶的聯繫人、判斷使用者的目前狀態,以及判斷使用者的 IM 功能, (立即訊息、視訊聊天、VOIP 等) 。

  5. 它會取得本機用戶聯繫人的目前狀態資訊。

  6. 當 IM 用戶端應用程式關閉時,Office 應用程式會以無訊息方式中斷連線。

探索 IM 應用程式

Office 應用程式會在登錄中尋找數個特定的金鑰和專案,以探索預設 IM 用戶端應用程式。 如果探索到預設 IM 用戶端應用程式,則會嘗試連線到該應用程式。

Office 應用程式探索預設 IM 用戶端應用程式所經歷的程式如下:

  1. Office 應用程式會查看登錄中的 HKEY_CURRENT_USER\Software\IM Providers\DefaultIMApp 子機碼是否已設定,並讀取該處列出的應用程式名稱。

  2. Office 應用程式接著會讀取 HKEY_CURRENT_USER\Software\IM Providers\ 應用程式名稱\UpAndRunning 機碼,並監視值的變更。

  3. Office 應用程式接著會讀取 HKEY_LOCAL_MACHINE\Software\IM Providers\ 應用程式名稱 登錄機碼,並取得儲存) 值 (CLSID 的 ProcessName 和類別標識符。

  4. 一旦 IM 用戶端應用程式順利完成其啟動順序,並正確註冊所有類別以進行目前狀態整合,它會將 HKEY_CURRENT_USER\Software\IM Providers\ Application name\UpAndRunning 機碼設定為 “2”,表示用戶端應用程式正在執行。

  5. 當 Office 應用程式發現 HKEY_CURRENT_USER\Software\IM Providers\ 應用程式 名稱\UpAndRunning 金鑰已設定為 「2」 時,它會檢查電腦上執行中進程的清單,以取得 IM 用戶端應用程式的進程名稱。

  6. 一旦 Office 應用程式找到 IM 用戶端應用程式使用的進程,Office 應用程式就會使用 CLSID 呼叫 CoCreateInstance ,以建立與 IM 用戶端應用程式的連線,做為跨進程 COM 伺服器。

驗證 IM 應用程式的連線

在 Office 應用程式建立 IM 用戶端應用程式的連線之後,它會執行下列動作:

  1. Office 應用程式會呼叫 IUnknown::QueryInterface 方法來檢查 IUCOfficeIntegration 介面。

  2. Office 應用程式接著會呼叫 IUCOfficeIntegration.GetAuthenticationInfo 方法,並傳入支援的最高整合版本 (例如 “15.0.0.0”) 。

  3. 如果 IM 用戶端應用程式支援以參數形式傳入的 Office 版本,應用程式會將下列硬式編碼 XML 字串傳回給呼叫端程式代碼:

    <authenticationinfo>

    注意事項

    基於舊版理由,如果IM用戶端應用程式支援以參數形式傳入的 Office 版本,則必須將確切值 <authenticationinfo> 傳回至 GetAuthenticationInfo 的呼叫。

  4. 如果 IM 用戶端應用程式無法傳回值,Office 應用程式會再次呼叫 GetAuthenticationInfo 方法,其中包含下一個支援的最高 Office (版本,例如 “14.0.0.0”) 。

  5. 一旦 Office 判斷 IM 用戶端應用程式支援 IM 和目前狀態整合,它會連線到一組必要的介面,以完成初始化。 (如需詳細資訊,請 參閱連線到必要的 interfaces.)

如果 Office 應用程式在上述任何步驟上遇到錯誤,它會退回,而且在 Office 應用程式的會話期間不會再次建立目前狀態整合。

聯機到必要的介面

驗證 IM 用戶端應用程式的連線之後,Office 應用程式會嘗試連線到 IM 用戶端應用程式必須公開的一組必要介面。 Office 應用程式會執行下列動作來完成此作業:

  • Office 應用程式會藉由呼叫 IUCOfficeIntegration.GetInterface 方法,從 UCCollaborationLib.OIInterface 列舉傳入 oiInterfaceLyncClient 常數,以取得 ILyncClient 物件。

  • Office 應用程式會呼叫 IUCOfficeIntegration.GetInterface 方法,從 OIInterface 列舉傳入 oiInterfaceAutomation 常數,以取得 IAutomation 物件。

  • Office 應用程式會設定 _ILyncClientEvents 事件接聽程式。

  • Office 應用程式會設定 _IUCOfficeIntegrationEvents 事件接聽程式。

  • Office 應用程式會藉由存取 ILyncClient.State 屬性,從 IM 用戶端應用程式取得登入狀態。

  • Office 應用程式會藉由呼叫 IUCOfficeIntegration.GetSupportedFeatures 方法來取得 IM 用戶端應用程式的功能,該方法會從 UCCollaborationLib.OIFeature 列舉傳回旗標。

  • Office 應用程式會存取 ILyncClient.Self 屬性,以取得 ISelf 對象的參考。

擷取本機使用者的功能

Office 應用程式會執行下列動作來取得本機使用者的功能:

  1. 如果 IM 用戶端應用程式支援 IClient2 介面,Office 會嘗試存取 IClient2.PrivateContactManager 屬性來取得 IContactManager 物件。

  2. 如果 IM 應用程式不支援 IClient2 介面,Office 應用程式會存取 ILyncClient.ContactManager 屬性來取得 IContactManager 物件。 IM 用戶端應用程式必須成功傳回 IContactManager 物件,才能建立任何其他 IM 功能。

  3. Office 應用程式會存取 ILyncClient.Uri 屬性,然後呼叫 IContactManager.GetContactByUri 來取得與本機使用者相關聯的 IContact 物件。

  4. 接著,Office 應用程式會對 IContact.CanStart 進行數次呼叫,以建立本機使用者的功能,並連續傳入 ModalityTypes.ucModalityInstantMessageModalityTypes.ucModalityAudioVideo 的值。

擷取聯繫人狀態

Office 應用程式會執行下列動作來取得聯繫人,包括本機使用者:

  1. Office 應用程式會呼叫 IContact.GetContactInformation 以從聯繫人取得目前狀態專案。

  2. Office 應用程式接著會訂閱聯繫人的目前狀態變更。 它會呼叫 IContactManager.CreateSubscription 來取得 IContactSubscription 物件。 然後呼叫 IContactSubscription.AddContact 將聯繫人新增至訂用帳戶,然後呼叫 IContactSubscription.Subscribe 以取得聯繫人狀態的變更。

  3. 如果IM應用程式支援 IContact2,Office會藉由呼叫 IContact2.BatchGetContactInformation2 來嘗試取得目前狀態資訊。

  4. 接著,Office 應用程式會呼叫 IContact.BatchGetContactInformation 來擷取聯繫人的目前狀態屬性。 Office 應用程式可以存取 IContact.Settings 屬性來取得第二組目前狀態屬性。

  5. 最後,Office 應用程式會存取 IContact.CustomGroups 屬性,以取得聯繫人的群組成員資格。 這會傳回 IGroupCollection 集合,其中包含聯繫人所屬的所有 IGroup 物件。

中斷與 IM 應用程式的連線

當 Office 應用程式從 IM 應用程式偵測 到 OnShuttingDown 事件時,它會以無訊息方式中斷連線。 不過,如果 Office 應用程式在 IM 應用程式之前關閉,Office 應用程式不保證會清除連線。 IM 應用程式必須處理用戶端連線流失。

設定登錄機碼和專案

如先前所述,具備IM功能的Office 應用程式會在登錄中尋找特定的密鑰、專案和值,以探索要連線的 IM 用戶端應用程式。 這些登錄值會為 Office 應用程式提供類別的進程名稱和 CLSID,以作為 IM 用戶端應用程式物件模型的進入點, (也就是實作 IUCOfficeIntegration 介面的類別) 。 Office 應用程式會共同建立該類別,並以用戶端身分連線到 IM 用戶端應用程式中的跨進程 COM 伺服器。

使用表 1 來識別必須在登錄中寫入的索引鍵、專案和值,以整合 IM 用戶端應用程式與 Office。

表 1. 用於設定預設 IM 用戶端應用程式的登錄機碼

機碼 Entry 類型 Value 範例
<HKEY_LOCAL_MACHINE\Software\IM Providers\應用程式名稱>
FriendlyName
REG_SZ
第三方 IM 用戶端應用程式的名稱。 Litware IM 2012
ProcessName
REG_SZ
第三方 IM 用戶端應用程式的進程名稱。 litware.exe
GUID
REG_SZ
在實作 IUCOfficeIntegration 介面) 的類別 (,IM 應用程式中可共存根類別的類別標識碼 (CLSID) 。 (GUID)
HKEY_CURRENT_USER\Software\IM Providers
DefaultIMApp
REG_SZ
IM 用戶端應用程式的名稱。 這必須與HKEY_LOCAL_MACHINE中hive) 的最上層登錄機碼 (名稱相同。 Litware
<HKEY_CURRENT_USER\Software\IM Providers\應用程式名稱>
UpAndRunning
REG_DWORD
介於 0 和 2 之間的整數值:
0—未執行
1— 開始
2— 執行中

注意:應用程式名稱登錄機碼必須與 DefaultIMApp 專案的值相同。

實作與 Office 整合所需的介面

UCCollaborationLib 命名空間有三個介面,可執行檔 (或 IM 用戶端應用程式的 COM 伺服器) 必須實作,才能與 Office 整合。 如果未實作這些介面,Office 應用程式會在初始化程式期間回復,而且不會建立與 IM 用戶端應用程式的連線。

所需的介面如下所示:

  • IUCOfficeIntegration- 雖然並非必要,但 _IUCOfficeIntegrationEvents 介面也應該在相同的衍生類別中實作。

  • ILyncClient- 雖然並非必要,但 _ILyncClientEvents 介面也應該在相同的衍生類別中實作。

  • IAutomation

IUCOfficeIntegration 介面

IUCOfficeIntegration 介面提供 Office 應用程式連線到 IM 用戶端應用程式的進入點。 介面會定義 Office 應用程式在起始與 IM 用戶端應用程式連線的程式中呼叫的三種方法。 實作 IUCOfficeIntegration 介面的類別必須是可共同建立的,這樣 Office 才能共同建立它的實例。 此外,它必須公開輸入的CLSID,做為 HKEY_LOCAL_MACHINE\Software\IM Providers\ 應用程式 名稱 登錄機碼中 GUID 專案的值。

繼承自 IUCOfficeIntegration 的 類別也應該實 作_IUCOfficeIntegrationEvents 介面。 _IUCOfficeIntegrationEvents介面包含公開 IUCOfficeIntegration 介面之事件處理程序的成員。

表 2 顯示必須在繼承自 IUCOfficeIntegration 和 _IUCOfficeIntegration 的 類別中實 的成員。

注意事項

如需 IUCOfficeIntegration_IUCOfficeIntegrationEvents 介面及其成員的詳細資訊,請參閱 UCCollaborationLib.IUCOfficeIntegrationUCCollaborationLib._IUCOfficeIntegrationEvents

表 2. IUCOfficeIntegration 和 _IUCOfficeIntegrationEvents 介面的實作

介面 Member 描述
IUCOfficeIntegration
GetAuthenticationInfo 方法
取得驗證資訊字串。
GetInterface 方法
取得特定版本的介面。
GetSupportedFeatures 方法
取得支援的 Office 整合功能。
_IUCOfficeIntegrationEvents
OnShuttingDown 事件
IM 用戶端應用程式嘗試關閉時引發的事件。

使用下列程式代碼來定義繼承自 IUCOfficeIntegration 的類別,並在 IM 用戶端應用程式中 _IUCOfficeIntegration 介面。

// An example of a class that can be co-created and can integrate
// with Office as an IM provider.
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(_IUCOfficeIntegrationEvents))]
[Guid("{CLSID value}"), ComVisible(true)]
public class LitwareClientAppObject : IUCOfficeIntegration
{
    // Implementation details omitted.
}

GetAuthenticationInfo 方法會採用字串作為 version 參數的自變數。 當 Office 應用程式呼叫這個方法時,會根據 Office 的版本,傳入自變數的兩個字串之一。 當 Office 應用程式為 方法提供 IM 用戶端應用程式所支援 (的 Office 版本,也就是支援功能) 時, GetAuthenticationInfo 方法會傳回硬式編碼的 XML 字串 <authenticationinfo>

使用下列程式代碼在 IM 用戶端應用程式程式碼內實作 GetAuthentication 方法。

public string GetAuthenticationInfo(string _version)
{
    // Define the version of Office that the IM client application supports.
    string supportedOfficeVersion = "15.0.0.0";
    // Do a simple check for equivalency.
    if (supportedOfficeVersion == _version)
    {
        // If the version of Office is supported, this method must 
        // return the string literal "<authenticationinfo>" exactly.
        return "<authenticationinfo>";
    }
    else
    {
        return null;
    }
}

GetInterface 方法會根據作為介面參數自變數傳入的內容,將類別的參考傳遞給呼叫的程序代碼。 當 Office 應用程式呼叫 GetInterface 方法時,它會傳入介面參數的兩個值之一: oiInterfaceILyncClient 常數 (1) 或 oiInterfaceIAutomation 常數 (2) UCCollaborationLib.OIInterface 列舉。 如果 Office 應用程式傳入 oiInterfaceILyncClient 常數, GetInterface 方法會傳回實作 ILyncClient 介面之類別的參考。 如果 Office 應用程式傳入 oiInterfaceIAutomation 常數, GetInterface 方法會傳回實作 IAutomation 介面的類別。

使用下列程式代碼範例,在 IM 用戶端應用程式程式代碼內實作 GetInterface 方法。

public object GetInterface(string _version, OIInterface _interface)
{
    // These objects implement the ILyncClient or IAutomation 
    // interfaces respectively. There is no restriction on what these
    // classes are named.
    IMClient imClient = new IMClient();
    IMClientAutomation imAutomation = new IMClientAutomation();
    // Return different object references depending on the value passed in
    // for the _interface parameter.
    switch (_interface)
    {
        // The calling code is asking for an object that inherits
        // from ILyncClient, so it returns such an object.
        case OIInterface.oiInterfaceILyncClient:
        {
            return imClient;
        }
        // The calling code is asking for an object that inherits
        // from IAutomation, so it returns such an object.
        case OIInterface.oiInterfaceIAutomation:
        {
            return imAutomation;
        }
        default:
        {
            throw new NotImplementedException();
        }
    }
}

GetSupportedFeatures 方法會傳回 IM 用戶端應用程式所支援 IM 功能的相關信息。 它只接受字串作為其唯一的參數 version。 當 Office 應用程式呼叫 GetSupportedFeatures 方法時,方法會從 UCCollaborationLib.OIFeature 列舉傳回值。 傳回的值會指定 IM 用戶端的功能,其中 IM 用戶端應用程式的每個功能都會藉由將旗標新增至 值來表示給 Office 應用程式。

注意事項

Office 2013 (和更新版本) 應用程式會忽略 OIFeature 列舉中的下列常數:

  • oiFeaturePictures (2)
  • oiFeatureFreeBusyIntegration
  • oiFeaturePhoneNormalization

Office 365 2011 版 (和更新版本) 應用程式會忽略 OIFeature 列舉中的下列常數:

  • oiFeaturePictures (2)
  • oiFeaturePhoneNormalization

使用下列程式代碼範例,在 IM 用戶端應用程式程式代碼內實作 GetSupportFeatures 方法。

public OIFeature GetSupportedFeatures(string _version)
{
    OIFeature supportedFeature1 = OIFeature.oiFeatureQuickContacts;
    OIFeature supportedFeature2 = OIFeature.oiFeatureFastSearch;
    return (supportedFeature1 | supportedFeature2);
}

ILyncClient 介面

ILyncClient 介面會對應至 IM 用戶端應用程式本身的功能。 它會公開屬性,這些屬性會參考已登入應用程式的人員 (本機使用者,以 UCCollaborationLib.ISelf 介面) 表示、應用程式的狀態、本機用戶的聯繫人清單,以及數個其他設定。 當 Office 應用程式嘗試連線到 IM 用戶端應用程式時,會取得實作 ILyncClient 介面之對象的參考。 從該參考中,Office 可以存取 IM 用戶端應用程式的大部分功能。

此外,實作 ILyncClient 介面的類別也應該實 作_ILyncClientEvents 介面。 _ILyncClientEvents介面會公開數個監視 IM 用戶端應用程式狀態所需的事件。

表 3 顯示必須在繼承自 ILyncClient 和 _ILyncClientEvents 的 類別中實 的成員。

注意事項

數據表中未列出的任何 ILyncClient_ILyncClientEvents 介面成員都必須存在,但不需要實作。 存在但未實作的成員可能會擲回 NotImplementedExceptionE_NOTIMPL 錯誤。

如需 ILyncClient_ILyncClientEvents 介面及其成員的詳細資訊,請參閱 UCCollaborationLib.ILyncClientUCCollaborationLib._ILyncClientEvents

表格 3 ILyncClient 和 ILyncClientEvents 介面的實作

介面 Member 描述
ILyncClient
ContactManager 屬性
取得聯繫人群組管理員。
ConversationManager 屬性
取得交談管理員。
Self 屬性
取得 Self 物件。
SignIn 方法
啟動具有特定可用性的 IM 用戶端應用程式登入程式。
State 屬性
取得目前的平台狀態。
Uri 屬性
取得 IM 用戶端應用程式的 URI。
_ILyncClientEvents
OnStateChanged 事件
當 IM 用戶端應用程式狀態變更時引發。 您應該處理此事件並取得 eventData.NewState 屬性。 當應用程式中的任何子系統造成狀態變更時,所有系結至 IM 用戶端應用程式實例的進程都會引發 事件。

在初始化程序期間,Office 會存取 ILyncClient.State 屬性。 這個屬性必須從 UCCollaborationLib.ClientState 列舉傳回值。

private ClientState _clientState;
public ClientState State
{
    get
    {
        return this._clientState;
    }
}

State 屬性會儲存 IM 用戶端應用程式的目前狀態。 它必須在整個 IM 用戶端應用程式會話中設定和更新。 當 IM 用戶端應用程式登入、註銷或關閉時,它應該會設定 State 屬性。 最好在 ILyncClient.SignInILyncClient.SignOut 方法內設定此屬性,如下列範例所示。

// This field is of a type that implements the 
// IAsynchronousOperation interface.
private IMClientAsyncOperation _asyncOperation = new IMClientAsyncOperation();
// This field is of a type that implements the ISelf interface.
private IMClientSelf _self;
public IMClientAsyncOperation SignIn(string _userUri, string _domainAndUser, 
    string _password, object _IMClientCallback, object _state)
{
    ClientState _previousClientState = this._clientState;
    this._clientState = ClientState.ucClientStateSignedIn;
    // The IMClientStateChangedEventData class implements the 
    // IClientStateChangedEventData interface.
    IMClientStateChangedEventData eventData = 
        new IMClientStateChangedEventData(_previousClientState, 
        this._clientState);
    if (_userUri != null)
    {
        // During the sign-in process, create a new contact with
        // the contact information of the currently signed-in user.
        this._self = new IMClientSelf(IMContact.BuildContact(_userUri));
    }
    // Raise the _ILyncClientEvents.OnStateChanged event.
    OnStateChanged(this, eventData as UC.ClientStateChangedEventData);
    
    return this._asyncOperation;
    }
}

下列程式代碼範例示範如何使用 ILyncClientEventsIUCOfficeIntegrationEvents 介面來設定事件接聽程式。

using Microsoft.Office.Uc;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace SampleImplementation
{
    // Note: UCOfficeIntegration inherits from both IUCOfficeIntegration and _IUCOfficeIntegrationEvents_Event
    [ClassInterface(ClassInterfaceType.None), Guid("13c41ef9-eb90-4e94-8a7c-1e9d686bc019"), ComVisible(true)]
    [ComSourceInterfaces(typeof(_IUCOfficeIntegrationEvents))]
    public class MyInstantMessengerOfficeIntegration : UCOfficeIntegration
    {
        #region IUCOfficeIntegration implementation
        public string GetAuthenticationInfo(string _version)
        {
            return "";
        }
        public object GetInterface(string _version, OIInterface _interface)
        {
            return null;
        }
        public OIFeature GetSupportedFeatures(string _version)
        {
            return OIFeature.oiFeatureAddOneNoteToConversation;
        }
        #endregion
        #region _IUCOfficeIntegrationEvents support
        // This event implements void _IUCOfficeIntegrationEvents.OnShuttingDown();
        public event _IUCOfficeIntegrationEvents_OnShuttingDownEventHandler OnShuttingDown;
        // This method is called by the IM application when it is beginning to shut down.
        // The method will raise the OnShuttingDown event which is translated by .NET COM interop layer
        // into a call to _IUCOfficeIntegrationEvents.OnShuttingDown.
        // This notifies Office applications that the IM application is going away.
        internal void RaiseOnShuttingDownEvent()
        {
            if (this.OnShuttingDown != null)
            {
                this.OnShuttingDown();
            }
        }
        #endregion
    }
    // Note: LyncClient inherits from both ILyncClient and _ILyncClientEvents_Event
    // You must implement LyncClient because the event handlers in _ILyncClientEvents expect you to pass a LyncClient interface.
    [ComVisible(true)]
    [ComSourceInterfaces(typeof(_ILyncClientEvents))]
    public class MyInstantMessengerOfficeIntegration2 :
        Client,
        Client2,
        LyncClient
    {
        #region Interfaces
        public LyncClientCapabilityTypes Capabilities
        {
            get
            {
                throw new NotImplementedException();
            }
        }
        public ConferenceScheduler ConferenceScheduler
        {
            get
            {
                throw new NotImplementedException();
            }
        }
        public ContactManager ContactManager
        {
            get
            {
                throw new NotImplementedException();
            }
        }
        public ConversationManager ConversationManager
        {
            get
            {
                throw new NotImplementedException();
            }
        }
        public DelegatorClient[] DelegatorClients
        {
            get
            {
                throw new NotImplementedException();
            }
        }
        public DeviceManager DeviceManager
        {
            get
            {
                throw new NotImplementedException();
            }
        }
        public bool InSuppressedMode
        {
            get
            {
                throw new NotImplementedException();
            }
        }
        public ContactManager PrivateContactManager
        {
            get
            {
                throw new NotImplementedException();
            }
        }
        public RoomManager RoomManager
        {
            get
            {
                throw new NotImplementedException();
            }
        }
        public Self Self
        {
            get
            {
                throw new NotImplementedException();
            }
        }
        public ClientSettings Settings
        {
            get
            {
                throw new NotImplementedException();
            }
        }
        public SignInConfiguration SignInConfiguration
        {
            get
            {
                throw new NotImplementedException();
            }
        }
        public ClientState State
        {
            get
            {
                throw new NotImplementedException();
            }
        }
        public ClientType Type
        {
            get
            {
                throw new NotImplementedException();
            }
        }
        public string Uri
        {
            get
            {
                throw new NotImplementedException();
            }
        }
        public Utilities Utilities
        {
            get
            {
                throw new NotImplementedException();
            }
        }
        public ApplicationRegistration CreateApplicationRegistration(string _appGuid, string _appName)
        {
            throw new NotImplementedException();
        }
        public AsynchronousOperation Initialize(string _clientName, string _version = "0", string _clientShortName = "0", string _clientNameAbbreviation = "0", string _clientLongName = "0", SupportedFeatures _supportedFeatures = SupportedFeatures.ucAllFeatures, [IUnknownConstant] object _CommunicatorClientCallback = null, object _state = null)
        {
            throw new NotImplementedException();
        }
        public AsynchronousOperation Shutdown([IUnknownConstant] object _CommunicatorClientCallback, object _state)
        {
            throw new NotImplementedException();
        }
        public AsynchronousOperation SignIn(string _userUri = "0", string _domainAndUsername = "0", string _password = "0", [IUnknownConstant] object _CommunicatorClientCallback = null, object _state = null)
        {
            throw new NotImplementedException();
        }
        public AsynchronousOperation SignOut([IUnknownConstant] object _CommunicatorClientCallback, object _state)
        {
            throw new NotImplementedException();
        }
        #endregion
        #region _ILyncClientEvents support
        public event _ILyncClientEvents_OnStateChangedEventHandler OnStateChanged;
        public event _ILyncClientEvents_OnNotificationReceivedEventHandler OnNotificationReceived;
        public event _ILyncClientEvents_OnCredentialRequestedEventHandler OnCredentialRequested;
        public event _ILyncClientEvents_OnSignInDelayedEventHandler OnSignInDelayed;
        public event _ILyncClientEvents_OnCapabilitiesChangedEventHandler OnCapabilitiesChanged;
        public event _ILyncClientEvents_OnDelegatorClientAddedEventHandler OnDelegatorClientAdded;
        public event _ILyncClientEvents_OnDelegatorClientRemovedEventHandler OnDelegatorClientRemoved;
        // Notifies Office apps that the IM client state (signed out, signing in, singed in, signing out, etc) has changed.
        internal void RaiseOnStateChangedEvent(ClientStateChangedEventData eventData)
        {
            if (this.OnStateChanged != null)
            {
                this.OnStateChanged(this, eventData);
            }
        }
        // Notifies Office apps that the IM client has received a notification event from MAPI (e.g. autodiscover has finished)
        internal void RaiseOnNotificationReceivedEvent(LyncClientNotificationReceivedEventData eventData)
        {
            if (this.OnNotificationReceived != null)
            {
                this.OnNotificationReceived(this, eventData);
            }
        }
        // Notifies Office apps that the IM client has received a request for credentials for some operation (e.g. sign in, web search)
        internal void RaiseOnCredentialRequestedEvent(CredentialRequestedEventData eventData)
        {
            if (this.OnCredentialRequested != null)
            {
                this.OnCredentialRequested(this, eventData);
            }
        }
        // Notifies Office apps that the IM client has been delayed from signing in and gives an estimated delay time.
        internal void RaiseOnSignInDelayedEvent(SignInDelayedEventData eventData)
        {
            if (this.OnSignInDelayed != null)
            {
                this.OnSignInDelayed(this, eventData);
            }
        }
        // Notifies Office apps that the capabilities of this IM client have changed.
        internal void RaiseOnCapabilitiesChangedEvent(PreferredCapabilitiesChangedEventData eventData)
        {
            if (this.OnCapabilitiesChanged != null)
            {
                this.OnCapabilitiesChanged(this, eventData);
            }
        }
        // Notifies Office apps that a DelegatorClient object has been added to the IM client object.
        internal void RaiseOnDelegatorClientAdded(DelegatorClientCollectionEventData eventData)
        {
            if (this.OnDelegatorClientAdded != null)
            {
                this.OnDelegatorClientAdded(this, eventData);
            }
        }
        // Notifies Office apps that a DelegatorClient object has been removed from the IM client object.
        internal void RaiseOnDelegatorClientRemoved(DelegatorClientCollectionEventData eventData)
        {
            if (this.OnDelegatorClientRemoved != null)
            {
                this.OnDelegatorClientRemoved(this, eventData);
            }
        }
        #endregion
    }
}

IAutomation 介面

IAutomation 介面會自動化 IM 用戶端應用程式的功能。 它可用來開始交談、加入會議,以及提供擴充性窗口內容。

表 4 顯示必須在繼承自 IAutomation 的類別中實作的成員。

注意事項

數據表中未列出的任何 IAutomation 介面成員都必須存在,但不需要實作。 存在但未實作的成員可能會擲回 NotImplementedExceptionE_NOTIMPL 錯誤。

如需 IAutomation 介面及其成員的詳細資訊,請參閱 UCCollaborationLib.IAutomation

表格 4 IAutomation 介面的實作

Member 描述
StartConversation 方法
使用指定的交談模式開始交談。 傳回 IConversationWindow 的實例。

實作聯繫人目前狀態整合

除了先前所討論的三個必要介面之外,還有幾個其他介面對於在 Office 中啟用聯繫人目前狀態功能很重要。 包括下列各項:

IContact 介面

IContact 介面代表 IM 用戶端應用程式使用者。 介面會公開使用者的目前狀態、可用模式、群組成員資格和聯繫人類型屬性。 若要開始與其他使用者交談,您必須提供 該使用者的 IContact 實例

表 5 顯示必須在繼承自 IContact 的類別中實作的成員。

注意事項

數據表中未列出的任何 IContact 介面成員都必須存在,但不需要實作。 存在但未實作的成員可能會擲回 NotImplementedExceptionE_NOTIMPL 錯誤。

如需 IContact 介面及其成員的詳細資訊,請參閱 UCCollaborationLib.IContact

表格 5 IContact 介面的實作

Member 描述
CanStart 方法
如果可以在聯繫人上啟動指定類型的強制回應,則傳回 true
GetContactInformation 方法
從發佈連絡人取得一個目前狀態專案。
BatchGetContactInformation 方法
從發佈連絡人取得多個目前狀態專案。
Settings 屬性
取得聯繫人屬性的集合。
CustomGroups 屬性
取得聯繫人所屬的群組集合。

在初始化程序期間,Office 應用程式會呼叫 IContact.CanStart 方法來判斷本機使用者的 IM 功能。 CanStart 方法會採用 UCCollaborationLib.ModalityTypes 列舉中的旗標作為 _modalityTypes 參數的自變數。 如果目前的使用者可以參與要求的強制回應 (也就是,用戶能夠立即傳訊、音訊和視訊傳訊,或應用程式共用 ) ,CanStart 方法會傳回 true

public bool CanStart(ModalityTypes _modalityTypes)
{
    // Define the capabilities of the current IM client application
    // user by using flags from the ModalityTypes enumeration.
    ModalityTypes userCapabilities = 
        ModalityTypes.ucModalityInstantMessage | 
        ModalityTypes.ucModalityAudioVideo | 
        ModalityTypes.ucModalityAppSharing;
    // Perform a simple test for equivalency.
    if (_modalityType == userCapabilities) 
    {
        return true;
    }
    else 
    {
        return false;
    }
}

GetContactInformation 方法會從 IContact 物件擷取聯繫人的相關信息。 呼叫端程式代碼必須從 _contactInformationType 參數的 UCCollaborationLib.ContactInformationType 列舉傳入值,以指出要擷取的數據。

public object GetContactInformation(
    ContactInformationType _contactInformationType)
{
    // Determine the information to return from the contact's data based
    // on the value passed in for the _contactInformationType parameter.
    switch (_contactInformationType)
    {
        case ContactInformationType.ucPresenceEmailAddresses:
        {
            // Return the URI associated with the contact.
            string returnValue = this.Uri.ToLower().Replace("sip:", String.Empty);
            return returnValue;
        }
        case ContactInformationType.ucPresenceDisplayName:
        {
            // Return the display name associated with the contact.
            string returnValue = this._DisplayName;
            return returnValue;
        }
        default:
        {
            throw new NotImplementedException;
        }
        // Additional implementation details omitted.
    }
}

類似於 GetContactInformation,BatchGetContactInformation 方法會從 IContact 物件擷取關於聯繫人的多個目前狀態專案。 呼叫程式代碼必須從 _ contactInformationTypes 參數的 ContactInformationType 列舉傳入值陣列 。 方法會傳回包含所要求數據的 UCCollaborationLib.IContactInformationDictionary 物件。

public IMClientContactInformationDictionary BatchGetContactInformation(
    ContactInformationType[] _contactInformationTypes)
{
    // The IMClientContactInformationDictionary class implements the
    // IContactInformationDictionary interface.
    IMClientContactInformationDictionary contactDictionary = 
        new IMClientContactInformationDictionary();
    foreach (ContactInformationType type in _contactInformationTypes)
    {
        // Call GetContactInformation for each type of contact 
        // information to retrieve. This code adds a new entry to
        // a Dictionary object exposed by the
        // ContactInformationDictionary property.
        contactDictionary.ContactInformationDictionary.Add(
            type, this.GetContactInformation(type));
    }
    return contactDictionary;
}

IContact.Settings 屬性會傳回包含聯繫人相關自定義屬性的 IContactSettingDictionary 物件。

public IMClientContactSettingDictionary Settings
{
    get
    {
       // The IMClientContactSettingDictionary class implements
       // the IContactSettingDictionary interface.
       return new IMClientContactSettingDictionary();
    }
}

IContact.CustomGroups 屬性會傳回 IGroupCollection 物件,其中包含聯繫人為其成員的所有群組。

public IMClientGroupCollection CustomGroups
{
    get {
       // The IMClientGroupCollection class implements
       // the IGroupCollection interface.
        return new IMClientGroupCollection();
    }
}

ISelf 介面

在初始化程序期間,Office 應用程式會存取必須傳回 ISelf 物件的 ILyncClient.Self 屬性,以取得目前用戶的數據。 ISelf 介面代表本機登入 IM 用戶端應用程式使用者。

表 6 顯示必須在繼承自 ISelf 的類別中實作的成員。

注意事項

數據表中未列出 的任何 ISelf 介面成員都必須存在,但不需要實作。 存在但未實作的成員可能會擲回 NotImplementedExceptionE_NOTIMPL 錯誤。

表格 6 ISelf 介面的實作

Member 描述
Contact 屬性
取得與本機使用者相關聯的 IContact 物件。

本機使用者的目前狀態、可用模式、群組成員資格和聯繫人類型屬性會透過 ISelf.Contact 屬性 (公開,該屬性會傳回 IContact 物件) 。 在初始化程序期間,Office 應用程式會存取 ISelf.Contact 屬性,以取得本機用戶聯繫人信息的參考。

使用下列程式代碼來定義繼承自實作 Contact 屬性之 ISelf 介面的類別。

[ComVisible(true)]
public class IMClientSelf : ISelf
{
    // Declare a private field to store contact data for local user.
    private IMClientContact _contactData;
    // In the constructor for the ISelf object, the calling code 
    // must supply contact data.
    public IMClientSelf (IMClientContact _selfContactData)
    {
        this._contactData = _selfContactData;
    }
    // When accessed, the Contact property returns a reference
    // to the IContact object that represents the local user.
    public IMClientContact Contact
    {
        get
        {
            return this._contactData as IMClientContact;
        }
    }
    // Additional implementation details omitted.
}

IContactManager 和 _IContactManagerEvents 介面

IContactManager 物件會管理本機用戶的聯繫人,包括本機使用者自己的聯繫人資訊。 Office 應用程式會使用 IContactManager 物件來存取對應至本機用戶聯繫人的 IContact 物件。

表 7 顯示必須在繼承自 IContactManager 和 _IContactManagerEvents 的 類別中實 的成員。

注意事項

數據表中未列出 的任何 IContactManager 介面成員都必須存在,但不需要實作。 存在但未實作的成員可能會擲回 NotImplementedExceptionE_NOTIMPL 錯誤。

如需 IContactManager_IContactManagerEvents 介面及其成員的詳細資訊,請參閱 UCCollaborationLib.IContactManagerUCCollaborationLib._IContactManagerEvents

表格 7 IContactManager 和 _IContactManagerEvents 介面的實作

介面 Member 描述
IContactManager
GetContactByUri 方法
使用連絡人 URI 尋找或建立新的聯繫人實例。
CreateSubscription 方法
建立可用於批處理訂閱或查詢的 ISubscription 物件。
Lookup 方法
查閱聯繫人或通訊群組。
_IContactManagerEvents
OnGroupAdded 事件
當群組加入群組集合時引發。 更新的群組集合可以從 IContactManager.Groups 屬性取得。
OnGroupRemoved 事件
從群組集合中移除群組時引發。 更新的群組集合可以從 IContactManager.Groups 屬性取得。
OnSearchProviderStateChanged 事件
當搜尋提供者的狀態變更時引發。

Office 會使用聯繫人的 SIP 位址,呼叫 IContactManager.GetContactByUri 以取得聯繫人的目前狀態資訊。 當在 Active Directory 中為 SIP 位址設定聯繫人時,Office 會決定聯繫人的此位址,並呼叫 GetContactByUri,為 _contactUri 參數傳遞 聯繫人的 SIP 位址。

當 Office 無法判斷聯繫人的 SIP 位址時,它會呼叫 IContactManager.Lookup 方法,使用 IM 服務來尋找 SIP。 在這裡,Office 會傳入可為聯繫人 (找到的最佳數據,例如,只有聯繫人的電子郵件位址) 。 Lookup 方法會以異步方式傳回 AsynchronousOperation 物件。 當呼叫回呼時, Lookup 方法除了連絡的 URI 之外,也應該傳回作業的成功或失敗。

public IMClientContact GetContactByUri(string _contactUri)
{
    // Declare a Contact variable to contain information about the contact.
    IMClientContact tempContact = null;
    // The _groupCollections field is an IGroupCollection object. Iterate 
    // over each group in collection to see if the 
    // contact is a part of the group.
    foreach (IMClientGroup group in this._groupCollections)
    {
       if (group.TryGetContact(_contactUri, out tempContact))
       {
           break;
       }
    }
    // Check to see that the URI returned a valid contact. If it
    // did not, create a new contact.
    if (tempContact == null)
    {
        tempContact = IMClientContact.BuildContact(_contactUri);
    }
    // Return the contact to the calling code.
    return tempContact;
}

Office 應用程式必須訂閱個別聯繫人的目前狀態變更。 因此,當聯繫人的目前狀態變更時,IM 伺服器會警示 IM 用戶端應用程式,進而警示 Office 應用程式。 若要這樣做,Office 應用程式會呼叫 IContactManager.CreateSubscription 方法,為此要求建立新的 IContactSubscription 物件。

// Declare a private field to contain an IContactSubscription object.
private IMClientContactSubscription _contactSubscription;
// Return the IContactSubscription object associated 
// with the IContactManager object.
public IMClientContactSubscription CreateSubscription()
{
    return this._contactSubscription;
}

IGroup 和 IGroupCollection 介面

IGroup 物件代表聯繫人集合,這些聯繫人具有其他屬性,可依集體組名識別聯繫人集合。 IGroupCollection 物件代表本機使用者和 IM 用戶端應用程式所定義的 IGroup 物件集合。 Office 應用程式會使用 IGroupCollectionIGroup 物件來存取本機用戶的聯繫人。

表 9 顯示下表中繼承自 IGroup 和 IGroupCollection 之類別中必須實作的成員。

注意事項

數據表中未列出的任何 IGroup 介面成員都必須存在,但不需要實作。 存在但未實作的成員可能會擲回 NotImplementedExceptionE_NOTIMPL 錯誤。

如需 IGroupIGroupCollection 介面及其成員的詳細資訊,請參閱 UCCollaborationLib.IGroupUCCollaborationLib.IGroupCollection

表格 9 IGroup 和 IGroupCollection 介面的實作

介面 Member 描述
IGroupCollection
Count 屬性
傳回集合中 IGroup 物件的計數
Item 屬性
傳回集合中指定索引處的 IGroup 物件。
IGroup
Id 屬性
傳回群組的標識碼。

當 Office 應用程式取得本機使用者的資訊時,它會藉由呼叫 IContact.CustomGroups 屬性來存取聯繫人 (本機使用者) 的群組成員資格,該屬性會傳回 IGroupCollection 物件。 IGroupCollection 必須包含 IGroup 物件的陣列 (或清單) 。 衍生自 IGroupCollection 的 類別必須公開 Count 屬性,此屬性會傳回集合中的項目數目,以及索引器方法 ,這個 (int) ,這會從集合傳回 IGroup 物件。

IContactSubscription 介面

IContactSubscription 介面可讓您指定要接收目前狀態資訊更新的聯繫人,以及觸發通知的目前狀態信息類型。 Office 應用程式會使用 IContactSubscription 對象來註冊聯繫人目前狀態的變更。

表 10 顯示必須在繼承自 IContactSubscription 的類別中實作的成員。

注意事項

數據表中未列出 的任何 IContactSubscription 介面成員都必須存在,但不需要實作。 存在但未實作的成員可能會擲回 NotImplementedExceptionE_NOTIMPL 錯誤。

如需 IContactSubscription 介面及其成員的詳細資訊,請參閱 UCCollaborationLib.IContactSubscription

表 10. IContactSubscription 介面的實作

Member 描述
AddContact 方法
將聯繫人加入至訂用帳戶物件。
Subscribe 方法
協助 IM 用戶端應用程式監視連絡人是否存在。

IContactSubscription 介面必須包含它所監視之所有 IContact 對象的參考,使用陣列或清單IContactSubscription.AddContact 方法會將 的 IContact 物件新增至 IContactSubscription 物件的基礎數據結構,藉此新增聯繫人來監視目前狀態變更。

// Store references to all of the IContact objects to subscribe to.
private List<IMClientContact> _subscribedContacts;
// Add a new IContact object to the collection of contacts.
public void AddContact(IMClientContact _contact)
{
    this._subscribedContacts.Add(_contact);
}

IContactSubscription.Subscribe 方法可讓 IM 用戶端應用程式存取聯繫人的目前狀態觀察者。 它可以使用輪詢策略,從伺服器取得 IM 用戶端應用程式已訂閱之聯繫人的存在狀態。 在要求使用者聯繫人清單以外的人員 (例如,從較大的公用網路) 時, Subscribe 方法會很有説明。

IContactEndPoint 介面

IContactEndPoint 代表聯繫人電話號碼集合中的電話號碼。

表11顯示必須在繼承自 IContactEndPoint的類別中實作的成員。

注意事項

數據表中未列出的任何 IContactEndPoint 介面成員都必須存在,但不需要實作。 存在但未實作的成員可能會擲回 NotImplementedExceptionE_NOTIMPL 錯誤。

如需 IContactEndPoint 介面及其成員的詳細資訊,請參閱 UCCollaborationLib.IContactEndpoint

表 11. IContactEndPoint 介面的實作

Member 描述
DisplayName 屬性
取得顯示字串。
Type 屬性
取得連絡人端點類型
Uri 屬性
取得連絡人 URI。

ILocaleString 介面

ILocaleString 是本地化的字串結構,同時包含當地語系化字串和當地語系化的地區設定識別符。 ILocaleString 介面可用來格式化聯繫人卡片上的自定義狀態字串。

表 12 顯示必須在繼承自 ILocaleString 的類別中實作的成員。

注意事項

數據表中未列出 的任何 ILocaleString 介面成員都必須存在,但不需要實作。 存在但未實作的成員可能會擲回 NotImplementedExceptionE_NOTIMPL 錯誤。

如需 ILocalString 介面及其成員的詳細資訊,請參閱 UCCollaborationLib.ILocaleString

表 12. ILocaleString 介面的實作

Member 描述
LocaleId 屬性
取得地區設定標識碼。
Value 屬性
取得字串。

另請參閱