Como sincronizar arquivos usando código não gerenciado

Este tópico mostra como usar uma linguagem não gerenciada, como C++, para criar um aplicativo que sincronize os arquivos e as subpastas usando o provedor de sincronização de arquivos do Sync Framework.

Este tópico pressupõe uma familiaridade básica com os conceitos de C++ e COM.

Os exemplos neste tópico se concentram nas seguintes interfaces do Sync Framework:

Noções básicas sobre sincronização de arquivos

O Sync Framework implementa um provedor de sincronização que pode ser usado para sincronizar arquivos e subpastas contidos em uma pasta em um sistema de arquivos. Esse provedor expõe várias configurações modificáveis para exercer mais controle sobre exatamente como a sincronização ocorre e quais itens são sincronizados. Para sincronizar arquivos entre duas pastas, um aplicativo executa estas etapas básicas:

  1. Cria um objeto IFileSyncProvider para representar cada pasta.

  2. Passa os dois provedores para um objeto ISyncSession e especifica um como o provedor de origem e o outro como o provedor de destino.

  3. Inicia a sessão de sincronização.

Para obter mais informações sobre a sincronização de arquivos, consulte Sincronizando arquivos.

Requisitos de compilação

  • Synchronization.h: declarações para os componentes principais do Sync Framework.

    #include <synchronization.h>
    
  • FileSyncProvider.h: declarações para o provedor de sincronização de arquivos.

    #include <filesyncprovider.h>
    
  • Synchronization.lib: biblioteca de importação para os componentes principais do Sync Framework.

  • FileSyncProvider.lib: biblioteca de importação para o provedor de sincronização de arquivos.

Exemplo

O código de exemplo mostra as seguintes tarefas:

  • Como criar e inicializar um provedor de sincronização de arquivos de origem e um provedor de sincronização de arquivos de destino.

  • Como estabelecer um filtro para controlar quais itens são incluídos na sincronização.

  • Como usar uma sessão de sincronização para sincronizar itens entre as pastas representadas pelos provedores.

Este exemplo usa uma caixa de diálogo de MFC (Microsoft Foundation Classes) para obter informações de filtro e pasta do usuário. As cadeias de caracteres inseridas por um usuário são empacotadas em objetos CString que, por sua vez, são usados para inicializar os provedores e o filtro.

Criando e inicializando um provedor de sincronização de arquivos

Crie um objeto IFileSyncProvider usando CoCreateInstance.

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

O provedor deve ser inicializado para poder ser usado. Essa também é uma oportunidade para fazer configurações. Essa implementação passa um filtro, pFilter, para controlar quais itens são incluídos na sincronização. A próxima seção mostra como configurar o filtro.

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

Usando um filtro de escopo de sincronização de arquivo

Crie um filtro usando o método IFileSyncProvider::CreateNewScopeFilter. Esse novo filtro não tem relação com o provedor que o criou. Para conectar um filtro a um provedor, passe o filtro para o método IFileSyncProvider::Initialize. Isso significa que apenas um filtro deve ser criado por sessão de sincronização, pois o mesmo filtro pode ser passado para ambos os provedores. Lembre-se de que as informações de filtro são armazenadas pelo provedor no método Initialize. Portanto, as alterações posteriores no filtro não serão refletidas no provedor.

Essa implementação obtém valores de opção de filtro do usuário usando uma caixa de diálogo de MFC. O código da caixa de diálogo não é mostrado. Mas os valores de opção são armazenados em vários objetos CString, como m_strFilenameExc. Nosso exemplo define as opções de filtro como os valores fornecidos pelo usuário.

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

Iniciando a sincronização

Agora que os provedores e o filtro foram configurados e inicializados, crie e inicie uma sessão de sincronização.

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

Exemplo de código completo

O código a seguir é o código completo deste exemplo. Os exemplos anteriores nesta seção foram tirados deste 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;
}

Consulte também

Referência

Interface IFileSyncProvider
Interface IFileSyncScopeFilter

Conceitos

Sincronizando arquivos
Componentes de sincronização de arquivos do Sync Framework