Win32API 階層化されたディレクトリを1度に作成する MakeSureDirectoryPathExists

通常ディレクトリを作成する場合は、CreateDirectory関数を用いるが、この関数では1度に階層化されたディレクトリを作成することができない。


例えば、以下の例ようにCreateDirectory関数で階層化されたディレクトリを作成しようとするとエラーになり、GetLastError関数の戻り値は「3(指定されたパスが見つかりません。)」となる。

  • 例:CreateDirectoryでカレントディレクトリに階層化されたディレクトリを作成する(エラーになる)
  •   if (!CreateDirectory(L".\\a\\b\\c\\d\\e\\f", NULL)) {//エラーになる
        printf("%d\n", GetLastError());
      }




    そこで、階層化されたディレクトリを1度に作成したい場合は、MakeSureDirectoryPathExists関数を用いる。

  • MakeSureDirectoryPathExistsのプロトタイプ
  • BOOL MakeSureDirectoryPathExists(
      PCSTR DirPath 
    );


  • 注意点として、MakeSureDirectoryPathExists関数を使う際には、「imagehlp.h」をインクルードし、「imagehlp.lib」をリンクする必要がある

  • 使用例
  • #include <windows.h>
    #include <stdio.h>
    #include <imagehlp.h>
    #pragma comment(lib, "imagehlp.lib")
    
    int main()
    {
      if (MakeSureDirectoryPathExists(".\\a\\b\\c\\d\\e")) {
        puts("succeeded.");  
      } else {
        puts("failed");
      }
      return 0;
    }



    コメントを受けての追記(2014/01/20):
    上記のMakeSureDirectoryPathExists関数の使用例のコードは、コード上はMakeSureDirectoryPathExists関数の引数に「a\b\c\d\e」が渡されていあますが、実行するとカレントディレクトリに「a\b\c\d」というディレクトリが作成されます。これは、直感的な動作ではないと思います。


    それでは、「a\b\c\d\e」というディレクトリを作成するためには(つまりパスの最後の部分までをディレクトリ名として扱うようにするためには)、ディレクトリ名文字列の最後に「\」を付ける必要があります。



    MSDNにもその旨の記述がありました。

    DirPath
    有効なパス名を指定する、null で終わる文字列へのポインタを指定します。パスの最後のコンポーネントがファイル名ではなくディレクトリである場合、文字列の最後に円記号(\)を記述しなければなりません。

    http://msdn.microsoft.com/ja-jp/library/cc428990.aspx (MSDNより)




    つまり、カレントディレクトリに「a\b\c\d\e」というディレクトリを作成する場合は、以下のコード(使用例2)のようにする必要があります。

    #include <windows.h>
    #include <stdio.h>
    #include <imagehlp.h>
    #pragma comment(lib, "imagehlp.lib")
    
    int main()
    {
      if (MakeSureDirectoryPathExists(".\\a\\b\\c\\d\\e\\")) {
        puts("succeeded.");  
      } else {
        puts("failed");
      }
      return 0;
    }



    ni66ling 様 ご指摘ありがとうございました。

    (ここまでコメントを受けての追記)



    参考
    http://msdn.microsoft.com/ja-jp/library/cc428990.aspx