다음을 통해 공유


방법: 비관리 코드를 사용하여 파일 동기화

이 항목에서는 C++ 등의 비관리 코드로 Sync Services for File Systems를 사용하여 파일 및 하위 폴더를 동기화하는 응용 프로그램을 만드는 방법을 보여 줍니다.

이 항목에서는 기본적인 C++ 및 COM 개념에 익숙하다고 가정합니다.

이 항목의 예제에서는 다음과 같은 Sync Framework 인터페이스를 중점적으로 설명합니다.

파일 동기화 이해

Sync Services for File Systems는 파일 시스템의 폴더에 들어 있는 파일과 하위 폴더를 동기화하는 데 사용할 수 있는 동기화 공급자를 구현합니다. 이 공급자에서 노출하는 구성 가능한 몇 가지 설정을 통해 동기화를 수행하는 정확한 방법 및 동기화 대상 항목을 세밀하게 제어할 수 있습니다. 응용 프로그램에서는 두 폴더 사이에서 파일을 동기화하기 위해 다음과 같은 기본적인 단계를 수행합니다.

  1. 각 폴더를 나타내는 IFileSyncProvider 개체를 만듭니다.

  2. 두 공급자를 ISyncSession 개체에 전달하고 하나를 원본 공급자로, 다른 하나를 대상 공급자로 지정합니다.

  3. 동기화 세션을 시작합니다.

파일 동기화에 대한 자세한 내용은 Sync Services for File Systems를 참조하십시오.

빌드 요구 사항

  • Synchronization.h: Sync Framework 핵심 구성 요소에 대한 선언

    #include <synchronization.h>
    
  • FileSyncProvider.h: Sync Services for File Systems 구성 요소에 대한 선언

    #include <filesyncprovider.h>
    
  • Synchronization.lib: Sync Framework 핵심 구성 요소에 대한 가져오기 라이브러리

  • FileSyncProvider.lib: Sync Services for File Systems 구성 요소에 대한 가져오기 라이브러리

예제

예제 코드에서는 다음과 같은 작업을 보여 줍니다.

  • 원본 파일 동기화 공급자 및 대상 파일 동기화 공급자를 만들고 초기화하는 방법

  • 동기화에 포함될 항목을 제어하는 필터를 설정하는 방법

  • 동기화 세션을 사용하여 공급자가 나타내는 폴더 사이에서 항목을 동기화하는 방법

이 예제에서는 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 대화 상자를 사용하여 필터 옵션 값을 사용자로부터 수집합니다. 대화 상자 코드는 나와 있지 않습니다. 그러나 옵션 값은 m_strFilenameExc 등의 몇 가지 CString 개체에 저장되어 있습니다. 예제에서는 필터 옵션을 사용자가 제공한 값으로 설정합니다.

// 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 인터페이스

개념

Sync Services for File Systems 구성 요소

기타 리소스

Sync Services for File Systems