油断大敵。
最後は指定フォルダへの移動を実装すれば完成です。File::MoveとDirectory::Moveを使えばスグに終わると思っていました。サクッとコードを書いて、テストをしてみると例外が発生する。msdnによると、どうも
たとえば、c:\mydir を c:\public に移動しようとしたところ、c:\public が既に存在する場合、このメソッドは IOException をスローします。"c:\\public" の下に "mydir" が存在しない場合は、destDirName パラメータとして "c:\\public\\mydir" を指定する必要があります。または、"c:\\newdir" などの新しいディレクトリ名を指定します。
に対応する必要があるらしい。んもー、使いづらい。しゃーないので、同じようにWindows APIを使う事にした。ちゃんと実装するのが面倒なのはわかるけどさぁ。下に書いた\を\\に置換するのも、条件を考えないと不具合が発生するハズ。
extern "C" { int MyMoveToFolder(LPCTSTR file, LPCTSTR folder_path) { SHFILEOPSTRUCT sh_file_operation_struct; int result = 1; LPTSTR file_copied = (LPTSTR)calloc(lstrlen(file) + 2, sizeof(TCHAR)); LPTSTR file_to = (LPTSTR)calloc(lstrlen(folder_path) + 2, sizeof(TCHAR)); FILEOP_FLAGS flags = FOF_ALLOWUNDO | FOF_NOCONFIRMMKDIR; lstrcpy(file_copied, file); lstrcpy(file_to, folder_path); ZeroMemory( &sh_file_operation_struct, sizeof(sh_file_operation_struct) ); sh_file_operation_struct.wFunc = FO_MOVE; sh_file_operation_struct.fFlags = flags; sh_file_operation_struct.pFrom = file_copied; sh_file_operation_struct.pTo = file_to; result = SHFileOperation(&sh_file_operation_struct); free(file_copied); free(file_to); return result; } }; int FileTool::MoveToFolder(String ^srcpath, String ^dstpath) { int result = 1; LPCTSTR src, dst; //¥を¥¥に置換する String^ folderPath = dstpath->Replace("\\", "\\\\"); Diagnostics::Trace::WriteLine(folderPath); IntPtr p = System::Runtime::InteropServices::Marshal::StringToHGlobalAuto(srcpath); src = static_cast<LPCTSTR>(p.ToPointer()); IntPtr q = System::Runtime::InteropServices::Marshal::StringToHGlobalAuto(folderPath); dst = static_cast<LPCTSTR>(q.ToPointer()); try { result = MyMoveToFolder(src, dst); } finally { System::Runtime::InteropServices::Marshal::FreeHGlobal(p); System::Runtime::InteropServices::Marshal::FreeHGlobal(q); } return result; }