Procédure : synchroniser des fichiers à l'aide de code non managé
Cette rubrique explique comment utiliser un langage non managé, tel que C++, pour créer une application qui synchronise des fichiers et des sous-dossiers en utilisant le fournisseur de synchronisation de fichiers Sync Framework.
Cette rubrique suppose une connaissance de base des concepts C++ et COM.
Les exemples de cette rubrique reposent sur les interfaces Sync Framework suivantes :
Présentation de la synchronisation des fichiers
Sync Framework implémente un fournisseur de synchronisation qui peut être utilisé pour synchroniser des fichiers et sous-dossiers contenus dans un dossier dans un système de fichiers. Ce fournisseur expose plusieurs paramètres configurables pour offrir plus de contrôle sur la façon exacte dont la synchronisation se produit et les éléments qui sont synchronisés. Pour synchroniser des fichiers entre deux dossiers, une application effectue les étapes de base suivantes :
Crée un objet IFileSyncProvider pour représenter chaque dossier.
Passe les deux fournisseurs à un objet ISyncSession et spécifie l'un comme fournisseur de source et l'autre comme fournisseur de destination.
Démarre la session de synchronisation.
Pour plus d'informations sur la synchronisation des fichiers, consultez Synchronisation des fichiers.
Configuration de génération
Synchronization.h : déclarations pour les composants principaux de Sync Framework.
#include <synchronization.h>
FileSyncProvider.h : déclarations pour le fournisseur de synchronisation de fichiers.
#include <filesyncprovider.h>
Synchronization.lib : bibliothèque d'importation pour les composants principaux de Sync Framework.
FileSyncProvider.lib : bibliothèque d'importation pour le fournisseur de synchronisation de fichiers.
Exemple
L'exemple de code présente les tâches suivantes :
Création et initialisation d'un fournisseur de synchronisation de fichiers sources et d'un fournisseur de synchronisation de fichiers de destination.
Définition d'un filtre pour contrôler les éléments qui sont inclus dans la synchronisation.
Utilisation d'une session de synchronisation pour synchroniser des éléments entre les dossiers représentés par les fournisseurs.
Cet exemple utilise une boîte de dialogue MFC (Microsoft Foundation Classes) pour obtenir des informations sur les dossiers et filtres de l'utilisateur. Les chaînes qu'un utilisateur a entrées sont empaquetées dans des objets CString, puis ces objets sont utilisés pour initialiser les fournisseurs et le filtre.
Création et initialisation d'un fournisseur de synchronisation de fichiers
Créez un objet IFileSyncProvider en utilisant CoCreateInstance.
IFileSyncProvider* pProvSrc = NULL;
hr = CoCreateInstance(CLSID_FileSyncProvider, NULL, CLSCTX_INPROC_SERVER,
__uuidof(pProvSrc), (void**)&pProvSrc);
Le fournisseur doit être initialisé avant de pouvoir être utilisé. Cela permet également de configurer des paramètres. Cette implémentation passe un filtre, pFilter, pour contrôler les éléments qui sont inclus dans la synchronisation. La section suivante indique comment configurer le filtre.
hr = pProvSrc->Initialize(*pguidReplicaSrc, pstrFolderSrc->GetString(),
pstrMetaSrc->GetString(), NULL,
FILESYNC_INIT_FLAGS_NONE, pFilter, NULL, NULL);
Utilisation d'un filtre d'étendue de synchronisation de fichiers
Créez un filtre en utilisant la méthode IFileSyncProvider::CreateNewScopeFilter. Ce nouveau filtre n'a aucune relation avec le fournisseur. Pour connecter un filtre à un fournisseur, passez le filtre à la méthode IFileSyncProvider::Initialize. Cela signifie qu'un seul filtre doit être créé par session de synchronisation, parce que le même filtre peut être passé aux deux fournisseurs. Gardez à l'esprit que les informations de filtre sont stockées par le fournisseur dans la méthode Initialize. Par conséquent, les modifications ultérieures apportées au filtre ne sont pas répercutées dans le fournisseur.
Cette implémentation obtient des valeurs d'option de filtre de l'utilisateur en utilisant une boîte de dialogue MFC. Le code de la boîte de dialogue n'est pas affiché. Toutefois, les valeurs d'option sont stockées dans plusieurs objets CString, tels que m_strFilenameExc. Notre exemple affecte aux options de filtre les valeurs fournies par l'utilisateur.
// 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();
}
Démarrage de la synchronisation
Maintenant que les fournisseurs et le filtre ont été configurés et initialisés, créez et démarrez une session de synchronisation.
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();
}
Exemple de code complet
Le code suivant est le code complet pour cet exemple. Les exemples précédents de cette section proviennent de ce code.
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;
}