Windowsにはフォルダを作成するAPIなどが数多く実装されている。そのうち有名なのは以下の5つだ。
int _tmkdir(LPCTSTR dirname); BOOL CreateDirectory(LPCTSTR lpPathName,LPSECURITY_ATTRIBUTES lpSecurityAttributes); BOOL CreateDirectoryEx(LPCTSTR lpTemplateDirectory,LPCTSTR lpNewDirectory,LPSECURITY_ATTRIBUTES lpSecurityAttributes); int SHCreateDirectory(HWND hwnd,LPCWSTR pszPath); int SHCreateDirectoryEx(HWND hwnd,LPCTSTR pszPath,SECURITY_ATTRIBUTES *psa);
■_tmkdir
対応:全プラットフォーム
最大パス長:不明
■CreateDirectory
対応:Windows 95以降
最大パス長:248文字(CreateDirectoryWは「\\?\」の付加で3万2000文字)
■CreateDirectoryEx
対応:Windows 95以降
最大パス長:MAX_PATH(CreateDirectoryExWは「\\?\」の付加で3万2000文字)
■SHCreateDirectory
対応:Windows 2000以降
最大パス長:MAX_PATH
ユニコードのみ対応
■SHCreateDirectoryEx
対応:Windows Me以降
最大パス長:248
これらのAPIは作成結果の戻り方も対応OSもさまざま。とりあえず利用するには以下のようにする。
#include "atlstr.h"
#include "direct.h"
bool CreateFolderBy_tmkdir(LPCTSTR pszFolder)
{
return ::_tmkdir(pszFolder) == 0 ? true : false;
}
bool CreateFolderByCreateDirectory(LPCTSTR pszFolder)
{
return ::CreateDirectory(pszFolder,NULL) ? true : false;
}
bool CreateFolderByCreateDirectoryEx(LPCTSTR pszFolder)
{
return ::CreateDirectoryEx(_T(""),pszFolder,NULL) ? true : false;
}
#include "shlobj.h"
bool CreateFolderBySHCreateDirectory(LPCWSTR pszFolder)
{
return ::SHCreateDirectory(NULL,pszFolder) == ERROR_SUCCESS ? true : false;
}
bool CreateFolderBySHCreateDirectoryEx(LPCTSTR pszFolder)
{
return ::SHCreateDirectoryEx(NULL,pszFolder,NULL) == ERROR_SUCCESS ? true : false;
}
bool Test(void)
{
bool ret_tmkdir;
bool retCreateDirectory;
bool retCreateDirectoryEx;
bool retSHCreateDirectory;
bool retSHCreateDirectoryEx;
CAtlString strMessage;
//フォルダを作成
ret_tmkdir = CreateFolderBy_tmkdir(_T("c:\\testA\\"));
retCreateDirectory = CreateFolderByCreateDirectory(_T("c:\\testB\\"));
retCreateDirectoryEx = CreateFolderByCreateDirectoryEx(_T("c:\\testC\\"));
retSHCreateDirectory = CreateFolderBySHCreateDirectory(L"c:\\testD\\");
retSHCreateDirectoryEx = CreateFolderBySHCreateDirectoryEx(_T("c:\\testE\\"));
strMessage = _T("1階層のフォルダ作成結果\n");
if(ret_tmkdir)
strMessage += _T("_tmkdir成功\n");
if(retCreateDirectory)
strMessage += _T("CreateDirectory成功\n");
if(retCreateDirectoryEx)
strMessage += _T("CreateDirectoryEx成功\n");
if(retSHCreateDirectory)
strMessage += _T("SHCreateDirectory成功\n");
if(retSHCreateDirectoryEx)
strMessage += _T("SHCreateDirectoryEx成功\n");
//一気に3階層のフォルダを作成
ret_tmkdir = CreateFolderBy_tmkdir(_T("c:\\test1\\test\\test\\"));
retCreateDirectory = CreateFolderByCreateDirectory(_T("c:\\test2\\test\\test\\"));
retCreateDirectoryEx = CreateFolderByCreateDirectoryEx(_T("c:\\test3\\test\\test\\"));
retSHCreateDirectory = CreateFolderBySHCreateDirectory(L"c:\\test4\\test\\test\\");
retSHCreateDirectoryEx = CreateFolderBySHCreateDirectoryEx(_T("c:\\test5\\test\\test\\"));
strMessage += _T("\n3階層のフォルダ作成結果\n");
if(ret_tmkdir)
strMessage += _T("_tmkdir成功\n");
if(retCreateDirectory)
strMessage += _T("CreateDirectory成功\n");
if(retCreateDirectoryEx)
strMessage += _T("CreateDirectoryEx成功\n");
if(retSHCreateDirectory)
strMessage += _T("SHCreateDirectory成功\n");
if(retSHCreateDirectoryEx)
strMessage += _T("SHCreateDirectoryEx成功\n");
::MessageBox(NULL,strMessage,_T(""),MB_OK);
return true;
}

ここでは「C:\」にそれぞれのAPIを利用してフォルダを作成した。実行結果を見ると、新しいフォルダを1つだけ作る場合はどのAPIも成功する。しかし一気に数階層のフォルダを作ろうとした場合にはSHCreateDirectory系以外は失敗した。
つまりSHCreateDirectory系以外を利用する場合は、複数のフォルダを一気に作ろうと試みないようにフォルダの存在をチェックしつつ実行する必要がある。
