2012-03-23 20 views

答えて

4

Windows APIを使用する準備ができている場合は、これを行う最も簡単な方法はSHFileOperationです。 FO_DELETE操作を使用し、ディレクトリ名のヌル終了を忘れないようにしてください。

+0

SHFileOperationはユーザーモードアプリケーションには効果的ですが、特に偽装を利用してUNCネットワーク共有上のディレクトリを削除する場合は、Windowsサービスから呼び出されたときには機能しません。 – WebDrive

3

通常、利用可能なライブラリメソッドがない場合、これは再帰によって行われます。関数はすべてのディレクトリエントリを繰り返し、 '普通の'ファイルを削除し、見つかったディレクトリパスで自身を呼び出します。これにより、ディレクトリツリー全体が破壊されます(私のWindowsバージョンでは、誤って自殺のパラメータが渡された場合にOSフォルダを破壊しないように、パスの明示的なチェックが行われます)。

2

これはラメであってもよいが、それは醜いですが、それは無視して、あまりにも簡単です

system("rd /s /q ..."); 

を使用して検討することができます。また、「ネットワーク共有上のファイルを処理する方法」がすべて整っています。どのような解決策が出てくるのかはおそらくrdの(不完全なおよび/または間違った)再実装であるため、外部プロセスを呼び出すことは実際にコードを再利用することになります。 ;-)

+0

rdが存在しない場合でもコンパイルエラーでさえもコードを再利用して移植できないようにしてください(この場合、厄介な作業を行い、FindFirstFile()/ FindNext()をDeleteFile()/ RemoveDirectory 。非常に小さなプログラムの場合、これは役に立つかもしれません。個人的には、私はそのコマンドが実際に存在するかどうか常にチェックします。 –

+0

@phresnel:問題はWindowsシステムのみで、「rd」はすべてのWindowsシステムでデフォルトで利用可能です。私は手足を外に出て、利用可能な 'rd'が利用可能である(SHFileOperationはWindows XP以降にのみ存在し、Windows Vistaでは廃止されている)SHFileOperationよりも可能性が高いと主張します。 –

+0

確率は私にとってはあまり意味がありません。個人的には、いくつかの機能がないとコンパイル時エラーが発生しません。システムを使用すると、コンパイル時にエラーが発生することはありません。このように、小さなシステム固有のプログラムの場合、これは問題ありません。しかし、私は大規模または長期のプログラムのためにそれに対してアドバイスをします。今から5,10,15年後のことは決して分かりません。突然誰もがMacやLinuxに移行したら、あなたはそのプラットフォームであなたの牛を動かしてもらいたいと思うでしょう。 –

7

最高の解決策は、使用できる場合はboost::filesystem::remove_allです。そうすれば、プラットフォーム固有のことを心配する必要はありません。私はプラットフォームに依存しない他のソリューションは認識していません。そうでなければ通常の方法はディレクトリを読み込み、それを再帰的に降下させることになります(ただし、ディレクトリの読み方はboost::filesystemまたはシステム依存コードを使用します)。

2

MSDNによると、SHFileOperationは相対パスで使用するとスレッドセーフではありません。絶対パスでのみ安全に使用できます。

私の代わりにこのコードを使用することをお勧めします:

double directory_delete(char *pathname) 
{ 
    string str(pathname); 
    if (!str.empty()) 
    { 
     while (*str.rbegin() == '\\' || *str.rbegin() == '/') 
     { 
      str.erase(str.size()-1); 
     } 
    } 
    replace(str.begin(),str.end(),'/','\\'); 

    struct stat sb; 
    if (stat((char *)str.c_str(),&sb) == 0 && 
     S_ISDIR(sb.st_mode)) 
    { 
      HANDLE hFind; 
      WIN32_FIND_DATA FindFileData; 

      TCHAR DirPath[MAX_PATH]; 
      TCHAR FileName[MAX_PATH]; 

      _tcscpy(DirPath,(char *)str.c_str()); 
      _tcscat(DirPath,"\\*"); 
      _tcscpy(FileName,(char *)str.c_str()); 
      _tcscat(FileName,"\\"); 

      hFind = FindFirstFile(DirPath,&FindFileData); 
      if (hFind == INVALID_HANDLE_VALUE) return 0; 
      _tcscpy(DirPath,FileName); 

      bool bSearch = true; 
      while (bSearch) 
      { 
       if (FindNextFile(hFind,&FindFileData)) 
       { 
        if (!(_tcscmp(FindFileData.cFileName,".") && 
         _tcscmp(FindFileData.cFileName,".."))) continue; 
        _tcscat(FileName,FindFileData.cFileName); 
        if ((FindFileData.dwFileAttributes & 
        FILE_ATTRIBUTE_DIRECTORY)) 
        { 
         if (!directory_delete(FileName)) 
         { 
          FindClose(hFind); 
          return 0; 
         } 
         RemoveDirectory(FileName); 
         _tcscpy(FileName,DirPath); 
        } 
        else 
        { 
         if (FindFileData.dwFileAttributes & 
          FILE_ATTRIBUTE_READONLY) 
          _chmod(FileName, _S_IWRITE); 

         if (!DeleteFile(FileName)) 
         { 
          FindClose(hFind); 
          return 0; 
         } 
         _tcscpy(FileName,DirPath); 
        } 
       } 
       else 
       { 
        if (GetLastError() == ERROR_NO_MORE_FILES) 
         bSearch = false; 
        else 
        { 
         FindClose(hFind); 
         return 0; 
        } 
       } 
      } 
      FindClose(hFind); 

      return (double)(RemoveDirectory((char *)str.c_str()) == true); 
    } 
    else 
    { 
     return 0; 
    } 
} 

あなたは、あなたがこれらのヘッダとが必要になります「されるよう-」など、あなたのcppファイルの先頭に自分のコードを使用したい場合:

#include <windows.h> // winapi 
#include <sys/stat.h> // stat 
#include <tchar.h> // _tcscpy,_tcscat,_tcscmp 
#include <string> // string 
#include <algorithm> // replace 

using namespace std; 

...私はそうだと思います。

私のコードは、この記事に基づいています。

http://www.codeguru.com/cpp/w-p/files/folderdirectorymaintenance/article.php/c8999/Deleting-a-Directory-Along-with-SubFolders.htm

私は強く安全性の問題とは別に、SHFileOperationを使用しないようにお勧めします、それは、Windows Vista以降IFileOperationに置き換えられました。

希望すると便利です。

関連する問題