多階層フォルダを一括作成する方法【Windows API】

2019年9月12日

CreateDirectory関数では一回の呼び出しで1つのフォルダを作成することしかできませんでした。「D:\ABC\DEF\GHI\」という感じの階層化された フォルダを一回の呼び出しで作成することはできないのです。 しかし「MakeSureDirectoryPathExists」を使用すれば一度に全てのフォルダを作成することができます。

使い方はパス名を指定するだけで、非常に簡単です。 パス名の記述は、ルートから開始して「\」で終了します。 この関数を使用する場合はimagehlp.libが必要になります。 作成中に失敗した場合はFALSEが返り、途中までに作成したフォルダは全て残ります。 エラー時のリカバリーは必要に応じて実装してください。

#include <imagehlp.h>
#pragma comment(lib, "imagehlp.lib")

if ( ! MakeSureDirectoryPathExists("D:\\HONE\\DAST\\YOIYOI\\HOHOHO\\") ) {
    printf("フォルダの作成処理が失敗しました!!\n");
}

基本的に上記の関数を使用することを推奨しますが、自前で実装する場合は 文字列操作とCreateDirectry関数の連続呼び出しで作成することも可能です。 使用法は「MakeSureDirectoryPathExists」と同じです。 挙動は「MakeSureDirectoryPathExists」とほぼ互換になっています。 権限の制御を行ないたい場合は自力で実装する必要があります。

// 関数の再帰的な作成 (自前処理)
// 
// [引数]
// szPath : フォルダ名(絶対パスで記述)
// 
// [返値]
// 成功時 : TRUE
// 失敗時 : FALSE

BOOL MakeDirectoryPath(char *szPath)
{
    char szMakePath[MAX_PATH+1];

    if (lstrlen(szPath) > MAX_PATH) {
        return FALSE;
    }

    for (int i = 0; i < lstrlen(szPath); i++) {
        szMakePath[i] = szPath[i];

        if (szPath[i] == '\\') {

            szMakePath[i+1] = '\0';

            // 同一名称のファイルやフォルダが存在しなければフォルダ作成
            if ( GetFileAttributes(szMakePath) == 0xFFFFFFFF ) {
                if ( ! CreateDirectory(szMakePath, NULL) ) {
                    return FALSE;
                }
            }

        }
    }

    return TRUE;
}if ( ! MakeDirectoryPath("D:\\HONE\\DAST\\YOIYOI\\HOHOHO\\") ) {
    printf("フォルダの作成処理が失敗しました!!\n");
}

Windows API

Posted by @erestage