備註
某些資訊與發行前產品有關,在正式發行產品之前可能會大幅修改。 Microsoft 對於此處提供的資訊,不做任何明確或隱含的保證。
使用 Windows.Devices.Enumeration API 將裝置配對為集合。
Windows 支援將多個裝置配對為一組。 平台支援兩種類型的集合。
- 自動探索到的集合。 當通訊協定(例如藍牙 LE)在配對主要端點時自動探索屬於集合的其他端點時,就會發生這種情況。 例如,當使用者透過藍牙 LE 配對右耳塞時,協定堆疊可能會發現左耳塞,因此,可以將兩者配對成一組。
- 明確設定。 當透過多個通訊協定探索到裝置時,這些會很有用。 例如,因特網列印通訊協定 (IPP) 印表機通常會透過三種通訊協定來探索:IPP、WSD 和 eSCL。 當探索到相同裝置的多個端點時,可以將這些端點明確配對為集合。
自動探索集的程式代碼範例 (藍牙樣式)
此程式碼範例會使用自定義配對對象來實作藍牙樣式的自動發現的設定配對。 如同自定義配對的一般實作,需要 配對要求的處理程序 來處理配對儀式。 在此情況下,程式代碼範例只會實作 僅限確認 配對儀式。 新的和有趣的部分是新增 配對 set-member-requested 處理程式。
set-member-handler 可以讓平台嘗試將傳入的裝置配對成一個集合。 如果沒有該處理程式,通訊協定堆疊就不會嘗試列舉配對集的成員。 在完成配對的過程中,藍牙協定會偵測並識別設定的成員,因此,集合處理程式會在配對流程處理程式完成後被呼叫。 在此流程中,設定處理程式通常會在儀式後僅被呼叫一次,此時集合成員的清單已經確定;這表示協定在配對期間會探索出所有可用的端點,且之後不會再探索其他端點。
此程式代碼範例會同步配對所有探索到的集合成員與用來配對主要裝置/端點的相同 BtSetPairing 例程。 也支援以平行方式配對它們,而且對於您的案例可能更有效率。 但為了簡單起見,這不會顯示在程式碼範例中。 由於我們也將 set 成員與 set 處理程式配對,因此它們可能會以遞歸方式產生要配對的更多集合成員。 但一般而言,探索到集合成員的 set 處理程式可能只會看到 探索已完成 ,且集合成員向量是空的。
備註
此程式代碼範例沒有較大案例或應用程式的內容;但應用程式可能需要追蹤其配對的裝置,以及配對結果。 這是為了讓應用程式了解整個集合配對作業是否成功。
備註
這些 API 通常是異步的。 配對作業有自己的背景工作線程,並在不同的線程上呼叫處理程式。 您的程式代碼不需要像此程式碼範例一樣頻繁地封鎖。
C++/WinRT 中的程式碼範例
void PairingTests::BtSetPairing(DeviceInformation device)
{
DevicePairingKinds ceremonies = DevicePairingKinds::ConfirmOnly;
auto customPairing = device.Pairing().Custom();
event_revoker ceremonyEventToken = customPairing.PairingRequested(
{ this, &PairingTests::PairingRequestedHandler });
event_revoker setEventToken = customPairing.PairingSetMembersRequested(
{ this, &PairingTests::PairingSetMembersRequestedHandler });
DevicePairingResult result = customPairing.PairAsync(ceremonies).get();
if (DevicePairingResultStatus::Paired == result.Status()) // Pairing worked.
else // Handle pairing failure.
}
void PairingTests::PairingRequestedHandler(DeviceInformationCustomPairing const&,
DevicePairingRequestedEventArgs const& args)
{
switch (args.PairingKind())
{
case DevicePairingKinds::ConfirmOnly:
args.Accept();
break;
default:
// This code example doesn't implement other ceremonies.
// The handler wouldn't be called for ceremonies that the app didn't register.
}
}
void PairingTests::PairingSetMembersRequestedHandler(DeviceInformationCustomPairing
const&, DevicePairingSetMembersRequestedEventArgs const& args)
{
switch (args.Status())
{
case DevicePairingAddPairingSetMemberStatus::SetDiscoveryCompletedByProtocol:
// This is the expected result if we started set pairing
// a Bluetooth device. Note: there still might be no set members.
break;
case DevicePairingAddPairingSetMemberStatus::SetDiscoveryPartiallyCompletedByProtocol:
// The protocol enumerated some but not all set members.
break;
case DevicePairingAddPairingSetMemberStatus::SetDiscoveryNotAttemptedByProtocol:
// Not expected for Bluetooth.
// This constant implies that the protocol likely doesn't support set-pairing.
default:
// The other constants aren't expected in an auto-discovered Bluetooth set scenario.
// Error handling can go here.
}
for (auto setMember : args.PairingSetMembers())
{
BtSetPairing(setMember);
}
}
明確集合的程式代碼範例 (IPP 樣式)
此程式代碼範例會使用自定義配對對對象來實作明確的集合配對。 如同自定義配對的一般實作,需要 配對要求的處理程序 來處理配對儀式。 在此情況下,程式代碼範例只會實作 僅限確認 配對儀式。 如同藍牙程式代碼範例,新奇的部分是加入 pairing-set-member-requested 處理程式。 set 成員處理程式可讓平台嘗試將裝置配對為集合。
相較於藍牙樣式集配對案例,此程式代碼範例會明確將裝置新增至集合。 而設定處理程序涉及與 IPP 印表機配對相關通訊協定的一些不同之處。 這表示客戶端會透過不同通訊協定來進行裝置探索,而且所有集合成員配對所建立的 PnP 狀態和列印佇列應該同步。
為了保持程式碼範例的實作簡單,本示例假設預先已經探索到一組集合成員端點的向量,並將其與主要裝置一起作為參數傳入。 例如,在典型的 IPP 案例中,會依任意順序探索端點。 因此,主要裝置可能已透過 WSD 探索;然後向量會包含代表透過 IPP 和 eSCL 探索到端點的裝置。 但是,任何組合都是可能的且有效的。 它會將設定成員新增至應用程式主線程上主要裝置的自定義配對對對象,然後呼叫 PairAsync。
備註
實際上,任何線程上隨時都可以將設定成員新增至自定義配對物件。 透過通訊協議的作業可能需要很長的時間,甚至可能遭到封鎖,直到逾時為止,因此重疊它們很有用。 請考慮利用 API 的平行處理原則來同時新增和配對裝置。 即使您仍在透過有線網路列舉裝置,這也是可能的。 將它們配成一組的優點仍然普遍適用。
透過此實作,主要集合成員將同時與其他集合成員配對。 集合成員在處理器中會逐一同步配對。 但同樣地,它們可以平行配對,以提高效率。
PnP 中的裝置節點物件通常會因為配對而建立。 在 IPP 的情況下,在配對之後,一律會為每個端點建立裝置節點。 此集合配對 API 會隱含同步處理集合中端點之間的裝置節點建立。 在此程式代碼範例的流程中,所有裝置節點都會同步處理,因為所有設定成員都會在配對開始之前新增。 如需此 API 如何在 PnP 中同步處理裝置節點的詳細資訊,請參閱本主題中的 一般評論 一節。
備註
此程式代碼範例沒有較大案例或應用程式的內容;但應用程式可能需要追蹤其配對的裝置,以及配對結果。 這是為了讓應用程式了解整個集合配對作業是否成功。
C++/WinRT 中的程式碼範例
void PairingTests::IppSetPairing(DeviceInformation device,
std::vector<DeviceInformation> const& setMemberDevices)
{
DevicePairingKinds ceremonies = DevicePairingKinds::ConfirmOnly;
auto customPairing = device.Pairing().Custom();
event_revoker ceremonyEventToken = customPairing.PairingRequested({ this,
&PairingTests::PairingRequestedHandler });
event_revoker setEventToken = customPairing.PairingSetMembersRequested({ this,
&PairingTests::PairingSetMembersRequestedHandler });
if (setMemberDevices)
{
for (auto setDevice : setMemberDevices)
{
customPairing.AddPairingSetMember(setDevice);
}
}
DevicePairingResult result = customPairing.PairAsync(ceremonies).get();
if (DevicePairingResultStatus::Paired == result.Status()) // Pairing worked.
else // Handle pairing failure.
}
void PairingTests::PairingRequestedHandler(DeviceInformationCustomPairing const&,
DevicePairingRequestedEventArgs const& args)
{
switch (args.PairingKind())
{
case DevicePairingKinds::ConfirmOnly:
args.Accept();
break;
}
}
void PairingTests::PairingSetMembersRequestedHandler(DeviceInformationCustomPairing const&,
DevicePairingSetMembersRequestedEventArgs args)
{
switch (args.Status())
{
case DevicePairingAddPairingSetMemberStatus::AddedToSet:
// This is the expected result of adding a set member(s)
// by calling the AddPairingSetMember method.
break;
case DevicePairingAddPairingSetMemberStatus::CouldNotBeAddedToSet:
// Means we failed to add set member(s).
break;
case DevicePairingAddPairingSetMemberStatus::SetDiscoveryNotAttemptedByProtocol:
default:
// The other constants aren't expected in an explicit set scenario.
// Error handling can go here.
}
for (auto setMember : args.PairingSetMembers())
{
IppSetPairing(setMember, nullptr);
}
}
一般評論
自動發現 (類似藍牙) 配對設定
此 API 是必要的,以實現類似藍牙的一組裝置配對,在主要端點配對後,通訊協定才會探索組成成員。 簡單的範例可能是一組無線耳塞。 當第一個耳塞配對完成時,裝置會通知計算機有第二個裝置要配對作為集合的一部分。 自定義配對 API 已擴充,可讓應用程式透過新的 新增集成員狀態 處理程式來處理設定作業。
明確 (IPP 樣式) 設定配對
同樣地,您也可以使用此 API 將任何關聯端點 (AEP) 裝置群組配對為集合。 使用自定義配對物件,您的應用程式可以隨時在任何線程上將其他端點新增至配對集。 這是有意設計的,因為透過網路進行裝置探索和配對可能會花很長時間,我們希望在可以避免的情況下,不要依序執行這些操作。
在探索無法輕易協調的多種通訊協定和裝置堆疊時,將裝置成套配對特別有用。 例如,Windows 可能會探索具有三種不同網路協定的新式網路印表機,每個通訊協定都會產生關聯端點。 在這種情況下,將所有三個端點配對成一個集合非常有用,原因有幾點:它可以避免透過網路傳輸浪費地重新探索,並創建一個高效的單一列印佇列。
即使網路印表機未配對為集合,列印後台處理程式仍會嘗試為每個使用者建立單一列印佇列,而不論是否可以透過數種通訊協議進行配對。 如果印表機起初是透過某個通訊協議配對,作業系統(OS)會嘗試透過其他支援的協議重新發現它,並在所有協議上建立關聯,以避免重複的印表佇列。 一般而言,OS 可以快速且成功地執行此作業,併產生一個簡化的列印佇列。
不過,如果應用程式已經探索到印表機的所有端點,則此重新探索步驟會浪費。 更糟的是,在印表機準備好使用之前,它可以增加長時間的延遲。 此外,如果通訊協定不同步或延遲,則緩衝處理器可能必須為相同的印表機建立額外的列印佇列,這會令終端使用者感到困惑。
當以集合形式一次性配對所有端點時,可避免潛在的緩慢重新發現。 它可確保 PnP 狀態已同步處理,並產生最佳的簡化列印佇列。
裝置節點同步處理
當裝置與這個 API 配對為集合時,產生的 PnP 裝置狀態會方便同步處理。 應用程式在何時可以新增群組成員時,API 並不加以限制;但平台在同步處理裝置節點時,則有一定的限制。 裝置節點同步處理會封鎖,直到集合中的所有端點完成配對為止。 之後,會一次性建立所有端點的裝置節點。 您可以在該點之後將更多成員新增至集合,但不會阻擋後續的裝置節點建立,而是會立即創建。
- 裝置節點建立 會在 下列情況下同步處理:
- 在配對開始之前,會新增設定成員。
- 在至少有一個集合成員尚未完成時,可以新增集合成員。
- 裝置節點的建立 沒有 同步進行:
- 新增的集合成員都已完成後的任何時間。
就實際而言,API 不允許應用程式控制儀式完成的時間,以影響裝置節點同步處理方式的這種行為。 最接近的近似值是應用程式選擇完成儀式的時間。 在應用程式儀式處理程式返回之前,配對過程暫時無法完成;因此,這是應用程式在所有集合成員完成前影響流程的最後機會。