Compartir a través de


Sincronizar archivos utilizando código no administrado

En este tema se muestra cómo se utiliza un lenguaje no administrado, como C++, para crear una aplicación que sincroniza archivos y subcarpetas mediante el proveedor de sincronización de archivos de Sync Framework.

En este tema se suponen conocimientos básicos de los conceptos de C++ y COM.

Los ejemplos de este tema se centran en las siguientes interfaces de Sync Framework:

Descripción de la sincronización de archivos

Sync Framework implementa un proveedor de sincronización que se puede utilizar para sincronizar los archivos y subcarpetas que están contenidos en una carpeta de un sistema de archivos. Este proveedor expone varios valores configurables para ofrecer un mayor control sobre cómo se produce exactamente la sincronización y qué elementos se sincronizan. Para sincronizar los archivos entre dos carpetas, una aplicación completa los pasos básicos siguientes:

  1. Crea un objeto IFileSyncProvider para representar cada carpeta.

  2. Pasa los dos proveedores a un objeto ISyncSession y especifica uno como el proveedor de origen y el otro como el proveedor de destino.

  3. Inicia la sesión de sincronización.

Para obtener más información acerca de cómo sincronizar archivos, vea Sincronizar archivos.

Requisitos de la compilación

  • Synchronization.h: declaraciones de los componentes básicos de Sync Framework.

    #include <synchronization.h>
    
  • FileSyncProvider.h: declaraciones del proveedor de sincronización de archivos.

    #include <filesyncprovider.h>
    
  • Synchronization.lib: biblioteca de importación de los componentes básicos de Sync Framework.

  • FileSyncProvider.lib: biblioteca de importación del proveedor de sincronización de archivos.

Ejemplo

El ejemplo de código muestra las tareas siguientes:

  • Crear e inicializar un proveedor de sincronización de archivos de origen y un proveedor de sincronización de archivos de destino.

  • Establecer un filtro para controlar qué elementos se incluyen en la sincronización.

  • Usar una sesión de sincronización para sincronizar los elementos entre las carpetas que se representan mediante proveedores.

En este ejemplo se utiliza un diálogo de MFC (Microsoft Foundation Classes) para obtener la carpeta y filtrar la información del usuario. Las cadenas que un usuario escribió se empaquetan en objetos CString y estos objetos se utilizan para inicializar los proveedores y el filtro.

Crear e inicializar un proveedor de sincronización de archivos

Cree un objeto IFileSyncProvider usando CoCreateInstance.

IFileSyncProvider* pProvSrc = NULL;
hr = CoCreateInstance(CLSID_FileSyncProvider, NULL, CLSCTX_INPROC_SERVER, 
    __uuidof(pProvSrc), (void**)&pProvSrc);

El proveedor debe inicializarse para poder utilizarse. También es la oportunidad de configurar cualquier valor. Esta implementación pasa un filtro, pFilter, para controlar qué elementos se incluyen en la sincronización. En la sección siguiente se muestra cómo configurar el filtro.

hr = pProvSrc->Initialize(*pguidReplicaSrc, pstrFolderSrc->GetString(),
    pstrMetaSrc->GetString(), NULL, 
    FILESYNC_INIT_FLAGS_NONE, pFilter, NULL, NULL);

Usar un filtro de ámbito de File Sync

Cree un filtro con el método IFileSyncProvider::CreateNewScopeFilter. Este filtro nuevo no tiene ninguna relación con su proveedor de creación. Para conectar un filtro a un proveedor, pase el filtro al método IFileSyncProvider::Initialize. Esto significa que solo se debe crear un filtro por cada sesión de sincronización, ya que el mismo filtro se puede pasar a ambos proveedores. Tenga en cuenta que el proveedor almacena la información del filtro en el método Initialize. Por consiguiente, los cambios posteriores en el filtro no se reflejarán en el proveedor.

Esta implementación obtiene los valores de las opciones de filtro del usuario utilizando un diálogo de MFC. El código del diálogo no se muestra. Pero los valores de las opciones están almacenados en varios objetos CString, como m_strFilenameExc. En nuestro ejemplo se establecen las opciones de filtro en los valores proporcionados por el usuario.

// 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();
}

Iniciar la sincronización

Ahora que los proveedores y el filtro se han configurado e inicializado, cree e inicie una sesión de sincronización.

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();
}

Ejemplo de código completo

El siguiente es el código completo de este ejemplo. Los ejemplos anteriores de esta sección se tomaron de este código.

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;
}

Vea también

Referencia

Interfaz IFileSyncProvider
Interfaz IFileSyncScopeFilter

Conceptos

Sincronizar archivos
Componentes de sincronización de archivos de Sync Framework