本主題示範如何使用 Unmanaged 語言 (如 C++) 建立應用程式,該應用程式會使用 Sync Framework 檔案同步處理提供者來同步處理檔案和子資料夾。
本主題假設您對 C++ 和 COM 已有基本的了解。
本主題中的範例著重於下列 Sync Framework 介面:
了解檔案同步處理
Sync Framework 會實作同步處理提供者,可用來同步處理檔案系統上資料夾中所包含的檔案和子資料夾。此提供者會公開一些可設定的設定值,能夠更細緻地控制同步處理發生的確切方式,以及所同步處理的確切項目。若要在兩個資料夾之間進行同步處理,應用程式要完成下列基本步驟:
建立 IFileSyncProvider 物件來代表每個資料夾。
傳遞兩個提供者給 ISyncSession 物件,然後指定其中一個做為來源提供者,指定另一個做為目的地提供者。
啟動同步處理工作階段。
如需同步處理檔案的詳細資訊,請參閱同步處理檔案。
組建需求
Synchronization.h:Sync Framework 核心元件的宣告。
#include <synchronization.h>FileSyncProvider.h:檔案同步處理提供者的宣告。
#include <filesyncprovider.h>Synchronization.lib:Sync Framework 核心元件的匯入程式庫。
FileSyncProvider.lib:檔案同步處理提供者的匯入程式庫。
範例
範例程式碼會示範下列工作:
如何建立及初始化來源檔案同步處理提供者和目的地檔案同步處理提供者。
如何建立篩選來控制同步處理中要包含的項目。
如何使用同步處理工作階段來同步處理由提供者所代表資料夾之間的項目。
此範例使用 MFC (Microsoft Foundation Classes) 對話方塊,從使用者取得資料夾和篩選資訊。使用者輸入的字串是封裝在 CString 物件之中,然後再使用這些物件來初始化提供者和篩選。
建立及初始化檔案同步處理提供者
使用 CoCreateInstance,建立 IFileSyncProvider 物件。
IFileSyncProvider* pProvSrc = NULL;
hr = CoCreateInstance(CLSID_FileSyncProvider, NULL, CLSCTX_INPROC_SERVER,
__uuidof(pProvSrc), (void**)&pProvSrc);
提供者必須先初始化才能使用。這也是設定任何設定值的機會。此實作會傳遞篩選 pFilter,以控制包含於同步處理中的項目。下一節說明如何設定篩選。
hr = pProvSrc->Initialize(*pguidReplicaSrc, pstrFolderSrc->GetString(),
pstrMetaSrc->GetString(), NULL,
FILESYNC_INIT_FLAGS_NONE, pFilter, NULL, NULL);
使用檔案同步處理範圍篩選
使用 IFileSyncProvider::CreateNewScopeFilter 方法,建立篩選。此新篩選與其建立提供者沒有任何關聯性。若要將篩選連接至提供者,請傳遞篩選給 IFileSyncProvider::Initialize 方法。也就是說,每個同步處理工作階段必須只建立一個篩選,因為相同的篩選可以同時傳遞給兩個提供者。請注意,篩選資訊是由提供者儲存於 Initialize 方法中,因此,之後的篩選變更不會反映在提供者中。
此實作使用 MFC 對話方塊,從使用者取得篩選選項值。此處不顯示對話方塊程式碼,但是選項值會儲存於多個 CString 物件中,例如 m_strFilenameExc。我們的範例將篩選選項設定為由使用者提供的值。
// Create a scope filter and fill it (some strings may be empty).
IFileSyncScopeFilter* pFilter = NULL;
hr = pProvSrc->CreateNewScopeFilter(&pFilter);
if (SUCCEEDED(hr))
{
hr = pFilter->SetFilenameExcludes(m_strFilenameExc.GetString());
if (SUCCEEDED(hr))
{
hr = pFilter->SetSubDirectoryExcludes(m_strDirExc.GetString());
}
if (SUCCEEDED(hr))
{
DWORD dwMask = wcstoul(m_strAttrExc.GetString(), NULL, 16);
hr = pFilter->SetFileAttributeExcludeMask(dwMask);
}
if (SUCCEEDED(hr))
{
// Only set the include list if we have something in it, because
// setting the include list to empty effectively excludes all files.
if (!m_strFilenameInc.IsEmpty())
{
hr = pFilter->SetFilenameIncludes(m_strFilenameInc.GetString());
}
}
if (SUCCEEDED(hr))
{
// Initialize the providers.
hr = pProvSrc->Initialize(*pguidReplicaSrc, pstrFolderSrc->GetString(),
pstrMetaSrc->GetString(), NULL,
FILESYNC_INIT_FLAGS_NONE, pFilter, NULL, NULL);
if (SUCCEEDED(hr))
{
hr = pProvDest->Initialize(*pguidReplicaDest, pstrFolderDest->GetString(),
pstrMetaDest->GetString(), NULL,
FILESYNC_INIT_FLAGS_NONE, pFilter, NULL, NULL);
}
}
pFilter->Release();
}
啟動同步處理
現在,提供者和篩選都已設定並初始化,就可以建立並啟動同步處理工作階段。
IApplicationSyncServices* pSvc = NULL;
hr = CoCreateInstance(CLSID_SyncServices, NULL, CLSCTX_INPROC_SERVER,
IID_IApplicationSyncServices, (void**)&pSvc);
if (SUCCEEDED(hr))
{
ISyncSession* pSession = NULL;
hr = pSvc->CreateSyncSession(pProvDest, pProvSrc, &pSession);
if (SUCCEEDED(hr))
{
SYNC_SESSION_STATISTICS syncStats;
hr = pSession->Start(CRP_NONE, &syncStats);
pSession->Release();
}
pSvc->Release();
}
完整的程式碼範例
下列程式碼是此範例的完整程式碼。本節中先前的範例都是取自此程式碼。
HRESULT CFileSynchronizerDlg::Synchronize(const GUID* pguidReplicaSrc, CString* pstrFolderSrc,
CString* pstrMetaSrc, const GUID* pguidReplicaDest, CString* pstrFolderDest,
CString* pstrMetaDest)
{
HRESULT hr = E_UNEXPECTED;
// Create the source and destination providers.
IFileSyncProvider* pProvSrc = NULL;
hr = CoCreateInstance(CLSID_FileSyncProvider, NULL, CLSCTX_INPROC_SERVER,
__uuidof(pProvSrc), (void**)&pProvSrc);
if (SUCCEEDED(hr))
{
IFileSyncProvider* pProvDest = NULL;
hr = CoCreateInstance(CLSID_FileSyncProvider, NULL, CLSCTX_INPROC_SERVER,
__uuidof(pProvDest), (void**)&pProvDest);
if (SUCCEEDED(hr))
{
// Create a scope filter and fill it (some strings may be empty).
IFileSyncScopeFilter* pFilter = NULL;
hr = pProvSrc->CreateNewScopeFilter(&pFilter);
if (SUCCEEDED(hr))
{
hr = pFilter->SetFilenameExcludes(m_strFilenameExc.GetString());
if (SUCCEEDED(hr))
{
hr = pFilter->SetSubDirectoryExcludes(m_strDirExc.GetString());
}
if (SUCCEEDED(hr))
{
DWORD dwMask = wcstoul(m_strAttrExc.GetString(), NULL, 16);
hr = pFilter->SetFileAttributeExcludeMask(dwMask);
}
if (SUCCEEDED(hr))
{
// Only set the include list if we have something in it, because
// setting the include list to empty effectively excludes all files.
if (!m_strFilenameInc.IsEmpty())
{
hr = pFilter->SetFilenameIncludes(m_strFilenameInc.GetString());
}
}
if (SUCCEEDED(hr))
{
// Initialize the providers.
hr = pProvSrc->Initialize(*pguidReplicaSrc, pstrFolderSrc->GetString(),
pstrMetaSrc->GetString(), NULL,
FILESYNC_INIT_FLAGS_NONE, pFilter, NULL, NULL);
if (SUCCEEDED(hr))
{
hr = pProvDest->Initialize(*pguidReplicaDest, pstrFolderDest->GetString(),
pstrMetaDest->GetString(), NULL,
FILESYNC_INIT_FLAGS_NONE, pFilter, NULL, NULL);
}
}
pFilter->Release();
}
if (SUCCEEDED(hr))
{
// Synchronize!
IApplicationSyncServices* pSvc = NULL;
hr = CoCreateInstance(CLSID_SyncServices, NULL, CLSCTX_INPROC_SERVER,
IID_IApplicationSyncServices, (void**)&pSvc);
if (SUCCEEDED(hr))
{
ISyncSession* pSession = NULL;
hr = pSvc->CreateSyncSession(pProvDest, pProvSrc, &pSession);
if (SUCCEEDED(hr))
{
SYNC_SESSION_STATISTICS syncStats;
hr = pSession->Start(CRP_NONE, &syncStats);
pSession->Release();
}
pSvc->Release();
}
}
pProvDest->Release();
}
pProvSrc->Release();
}
return hr;
}
請參閱
參考
IFileSyncProvider 介面
IFileSyncScopeFilter 介面