プログラミングメモ →目次


フォルダのコピー

 CreateDirectory()APIでフォルダコピーペーストを実現する方法のメモです。

CopyFolder()という再帰関数を作ります。

まずペースト先のフォルダを作成おきます。FindFirstFile()APIで、コピー元のフォルダ階層に走査します。走査の結果リストからファイル、及びフォルダを1つずつ処理します。ファイルである場合は、ペースト先のフォルダにCopyFile()APIで複製し、サブフォルダの場合は、CopyFolder()を再帰的に呼び出します。

失敗した場合は、GetLastError()APIで失敗原因を表示します。

ソースコード:

// フォルダコピー
BOOL CopyFolder(const CString& strExistingFolderPath, const CString& strNewFolderPath)
{
    // 新しいフォルダ作成
    if (!CreateDirectory(strNewFolderPath, NULL))
        return false;

    // フォルダ走査用のパス名作成
    CString strFindFilePathName = strExistingFolderPath + L"\\*.*";

    // フォルダ走査
    WIN32_FIND_DATA fd;
    HANDLE hFind = FindFirstFile( strFindFilePathName, &fd);
    if (INVALID_HANDLE_VALUE == hFind)
    {    
        return false;
    }

    do
    {
        if(_T('.') != fd.cFileName[0])
        {
            CString strFoundFilePathName_From = strExistingFolderPath + L"\\" + fd.cFileName;
            CString strFoundFilePathName_To = strNewFolderPath  + L"\\" + fd.cFileName;

            if (FILE_ATTRIBUTE_DIRECTORY & fd.dwFileAttributes)
            {    
                // フォルダの場合は、CopyFolderを回帰的に呼び出する
                if (!CopyFolder(strFoundFilePathName_From, strFoundFilePathName_To))
                {
                    FindClose(hFind);
                    return FALSE;
                }
            }
            else
            {    // ファイルの場合は、ファイルコピー
                if (!CopyFile(strFoundFilePathName_From, strFoundFilePathName_To, FALSE))
                {
                    FindClose(hFind);
                    return FALSE;
                }
            }
        }
    } while( FindNextFile(hFind, &fd));
    FindClose(hFind);
    return TRUE;
}


// フォルダコピーのテスト
void Test()
{
    bool b = CMiscHelper::CopyFolder(_T("C:\\Temp"), _T("C:\\Temp1"));
    if (!b)
    {
        LPVOID lpMsgBuf;
        DWORD dw = GetLastError(); 

        FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER | 
            FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL,
            dw,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPTSTR) &lpMsgBuf,
            0, NULL );
        AfxMessageBox((LPCTSTR)lpMsgBuf, MB_ICONEXCLAMATION);
        LocalFree(lpMsgBuf);
    }
}