建立公事包協調器
公事包協調器提供公事包協調不同版本檔的方法。
關於公事包協調器
公事包協調器結合了檔的不同輸入版本,以產生檔的單一新輸出版本。 您可能需要建立公事包協調器以支援檔案類型。 此概觀描述公事包協調器,並說明如何建立它們。
我們將討論下列主題:
和解
檔是可以複製和變更的資訊集合。 如果至少兩份檔的內容不同,則檔有不同的版本。 對帳會從兩個或多個初始版本產生單一版本的檔。 一般而言,已協調的版本是初始版本的資訊組合,並保留最新的或最有用的資訊。
當公事包判斷相同檔的兩個或多個複本不同時,對帳是由公事包所起始。 公事包可做為此內容中的啟動器,找出並啟動與指定檔案類型相關聯的公事包協調器。 協調器會比較檔,並決定要保留的檔部分。 某些協調器可能需要使用者互動才能完成對帳。 其他人可能會在沒有使用者互動的情況下完成對帳。 協調器可以包含在應用程式內,或是實作為 DLL 的延伸模組。
某些公事包協調器可能會建立一些心力。 檔是一份檔,通常具有與初始檔相同的檔案類型,其中包含未儲存在合併版本中的資訊。 一般會使用「隔離」來為作者提供快速的方式,以判斷其原始檔案中的資訊不在最終合併的版本中。 如果協調器支援擷取,它會為每個檔的原始版本建立一個原始版本。 除非啟動器要求它們,否則不會建立擷取。
有些公事包協調器會使用公事包,讓使用者終止對帳。 對於可能決定無法繼續對帳的使用者而言,這是一個重要功能。 協調器通常會在對帳需要使用者互動且可能冗長時提供終止物件。 在某些環境中,協調器可能會允許部分對帳,讓使用者暫時暫停對帳,並在稍後繼續。 不過,公事包目前不支援部分對帳。
建立公事包協調器
您可以實作對帳介面來建立公事包協調器。 協調器至少會實作IReconcilableObject介面和IPersistStorage 或 IPersistFile介面。 公事包會決定何時需要對帳,並呼叫 IReconcilableObject::Reconcile 方法來起始對帳。
雖然 IReconcilableObject::Reconcile 提供一組廣泛的對帳功能,但在大部分情況下,公事包協調器只會執行最少的對帳。 特別是,公事包不需要協調器支援產生或支援終止物件。 此外,協調器會執行單一由上至下對帳,且不得傳回REC_E_NOTCOMPLETE值;也就是說,它不應該嘗試部分對帳。
公事包提供 IReconcileInitiator 介面。 公事包協調器可以使用 IReconcileInitiator::SetAbortCallback 方法來設定終止物件。 公事包不會使用版本識別碼,因此,如果協調器使用 IReconcileInitiator中的對應方法要求檔,請提供舊版的檔。
公事包會傳遞至 IReconcilableObject::Reconcile 檔案 Monikers,代表要協調的檔版本。 公事包協調器會使用 IMoniker::BindToObject 或 IMoniker::BindToStorage 方法來取得版本的存取權。 後者通常較快,建議使用。 協調器必須釋放它系結至的任何物件或儲存體。
當公事包協調器使用 IMoniker::BindToStorage時,它會系結至一般儲存體 (資料流程) 或 OLE 定義的結構化儲存體。 如果協調器需要一般儲存體,它應該使用 IMoniker::BindToStorage 來要求 IStream 介面。 如果協調器需要結構化儲存體,它應該要求 IStorage 介面。 在這兩種情況下,它都應該要求唯讀直接 () 儲存體的存取權;讀取/寫入存取權可能無法使用。
最小公事包協調器通常會直接查看其他版本的儲存體,並以非常基本的方式處理内嵌物件,例如將兩個版本的物件合併在輸出版本中。
啟動器會使用 GetClassFile 函式所實作的邏輯子集來找出適當的公事包協調器,以判斷指定檔案的類型,然後在登錄中尋找與指定檔案類型相關聯的協調器類別。 像其他 Shell 元件一樣,公事包會只依副檔名來決定檔案類型。 檔案的副檔名必須具有 [公事包] 的已註冊檔案類型,才能叫用檔案的協調器。 安裝協調器時,您必須設定下列表單的登錄專案。
CLSID
{the file CLSID}
Roles
Reconciler
(Default) = {the reconciler-classid}
類別必須快速載入、必須指定_MULTIPLEUSE,而且除非針對對帳介面提供封送處理器,否則必須是 DLL) 中包含的進程伺服器 (,而不是在.exe檔案中實作的本機伺服器 () 。
對帳中的使用者互動
公事包協調器應該嘗試在沒有使用者互動的情況下執行對帳。 對帳越自動化,使用者對程式的認知就越好。
在某些情況下,使用者介入可能很重要。 例如,檔案系統可能需要使用者先檢閱變更,再接受合併的檔版本,或可能需要使用者批註來說明已進行的變更。 在這些情況下,啟動器不是公事包協調器,負責查詢使用者並執行使用者的指示。
在其他情況下,可能需要使用者介入,例如,當兩個版本以不相容的方式編輯時。 在這種情況下,啟動器或公事包協調器都必須查詢使用者,以取得如何解決衝突的指示。 一般而言,沒有啟動器可以依賴完成對帳,而不需要一些使用者互動。 另一方面,協調器可以選擇與使用者互動,以解決衝突,或要求啟動器這麼做。
協調内嵌物件
在協調檔時,如果公事包協調器本身發現無法協調的類型内嵌物件,就可以成為啟動器。 在此情況下,協調器必須以遞迴方式協調每個内嵌物件,並假設啟動器的所有責任。
為了執行遞迴,公事包協調器會載入物件並查詢適當的介面。 物件的處理常式必須支援 介面。 如果介面的任何方法傳回OLE_E_NOTRUNNING值,協調器必須執行 物件才能執行作業。 因為内嵌物件的程式碼不一定可用,所以協調器必須為此條件提供解決方案。 例如,協調器可能會在已協調的版本中包含舊版和新版本的内嵌物件。 協調器不得嘗試跨連結協調。
啟動器會儲存要合併的檔版本。 在許多情況下,啟動器可以存取每個版本的儲存體,並使用類似的儲存體來儲存對帳的結果。 不過,有時候啟動器可能有記憶體內建物件,其中沒有持續性版本可供使用。 當包含開啟内嵌物件的檔必須在儲存之前進行協調時,就會發生此情況。 在這種情況下,啟動器會在記憶體中找到的版本中儲存對帳結果。
啟動器會使用 IPersistStorage 介面來系結 (載入) 合併的版本。 如果已建立初始版本並使用初始版本的IPersistStorage::InitNew方法,啟動器就會使用IPersistStorage::Load方法。 載入合併的版本時,啟動器會使用 QueryInterface 來擷取 IReconcilableObject 介面的位址。 此介面可讓啟動器存取現有擷取器的儲存空間,並讓其能夠建立任何新垃圾的儲存空間。 然後,啟動器會指示介面執行對帳。 啟動器實際上會在 IPersistStorage 之前查詢 IPersistFile 介面。 如果協調器支援 IPersistFile,啟動器會透過 IPersistFile 操作複本,而不是 IPersistStorage 方法。 這允許對帳未儲存為複合檔案的檔案。
當對帳完成時,啟動器可以使用 IPersistStorage 或 IPersistFile 介面來儲存合併的版本。 在對帳期間,公事包協調器會視需要建立工作,並將其永續性位寫入儲存體。 如果合併的版本是資料流程,則傳遞至IPersistStorage::Load的IStorage介面包含名為 「Contents」 的資料流程,其儲存狀態設定為 STATEBITS_FLAT。 (您可以使用 IStorage::Stat 方法.) 合併之後設定狀態位,啟動器會以適當的方式寫入資料來儲存合併的版本。 它應該確保已針對儲存體設定STATEBITS_FLAT。
殘留
啟動器會藉由在呼叫IReconcilableObject::Reconcile方法時,將pstgNewResidues參數設定為有效的位址,以指出它是否想要運作。 如果協調器不支援建立REC_E_NORESIDUES,除非 dwFlags 參數指定RECONCILEF_NORESIDUESOK值,否則它必須立即傳回 REC_E_NORESIDUES 值。
公事包協調器會建立新的儲存元素,並將其複製到 pstgNewResidues所指向的陣列,以傳回啟動器。 若為結構化儲存空間,協調器會複製 IStorage 介面,並針對一般儲存空間輸入,它會複製 IStream 或具有STATEBITS_FLAT旗標集的 IStorage 介面。 協調器會使用 IStorage 來建立必要的儲存體,並使用 IStorage::CreateStream 為數據流和 IStorage::CreateStorage 建立結構化儲存體的一般儲存體。
啟動器會準備 pstgNewResidues ,讓它在 IStorage 命名空間的非保留部分中不包含任何元素。 公事包協調器會將每一個同步處理放在名稱對應至其初始版本順序的專案中。 例如,第一個擷取包含在 「1」 中,第二個則包含在 「2」 中,依此類傳。 如果已協調的物件本身產生一個擷取,它會在名為 「0」 的元素中找到。
公事包協調器會個別認可每個新建立的專案,以確保啟動器可以存取訊號。 不過,協調器不會認可 pstgNewResidues 本身。 啟動器負責認可此或處置它。
公事包協調器參考
本節包含對帳介面的相關資訊。 處理錯誤時,方法只能傳回明確定義為可能傳回值的錯誤值。 此外,方法必須在從錯誤傳回之前,先將位址當做參數傳遞至 Null 的所有變數。
公事包協調器介面和方法