2016-09-13 14 views
0

RemoveDirectory()は、削除のためのディレクトリのマークとしてのみ記載されています。私はディレクトリが実際に削除されていることを確認しなければならないアプリケーションがあります(同じ名前の新しいディレクトリを作成するか、ディレクトリを再帰的に削除するためです)。Windowsでディレクトリを削除する方法

最初に考えたのは、ディレクトリがまだ存在するかどうかをテストするためにGetFileAttributes()を使用するか、削除のためにSHFileOperation()を使用することでした。しかし、長いテストを実行すると、いずれの時点で両方のソリューションが失敗する - CreateDirectory()が失敗します。

解決方法はありますか?

+1

おそらく、ディレクトリの名前を(ランダムな名前に)変更して、削除のマークを付けることができます。最終的に削除されます。その後、元の名前のディレクトリを常に作成できます。 – rveerd

+0

ディレクトリで何かしようとすると、「アクセスが拒否されました」というエラーが表示されます。それはあなたが知っている方法です。解決策、まあ、いいえ。ファイルを上書きしようとすることと根本的に異なるわけではなく、そのファイルはすでに別のプロセスによって使用されています。あなたはそのプロセスを見つけたり、それが完了するまで待って解決しなければなりません。それは診断するのが難しい傾向がある自発的な原因です。アンチマルウェアや、プログラムの現在の作業ディレクトリを同じディレクトリに設定するなどです。 –

+1

誰が「削除のためだけにディレクトリをマークする」と言っていますか? MSDNでは、「RemoveDirectory関数は、閉じるときに削除のためにディレクトリをマークします。したがって、ディレクトリへの最後のハンドルが閉じられるまで、ディレクトリは削除されません。つまり、ディレクトリが使用中の場合は削除されません。しかし、 "最後のハンドルはdir"が閉じていると、削除されます - おそらくすぐに? "即座に"可能性がありますが、それでも必ずしも_synchronously_であるとは限りません。_stackoverflow.com/questions/2809788/impossible-to-remove-directory?rq=1 – i486

答えて

1

このvideoは、2015 CppConのDouglas Niallによって、溶液を約7:30から詳細にカバーしています。

考えられるのは、ファイルまたはディレクトリを同期して起こる別の場所(同じボリューム上)にリネーム(移動)し、それを削除することです。これは非同期に発生します。

は、このツリーを考えてみましょう:

C:\Users\me\ 
    foo\ 
    bar\ 
     obsolete.txt 

あなたがobsolete.txtを削除した後barを削除しようとobsolete.txt本当にが削除される前に遅延が発生する場合がありますので、それが失敗することがあります。

obsolete.txtを最初にC:\Users\meに移動し、ディレクトリ内の別のobsolete.txtと衝突しないように一時的な名前を付けたとします。 2DCD7863-456C-4B6C-AD84-C4F5E8009D81_obsolete.txtのように、GUIDの接頭辞を付けることもできます。その一時的な名前を使用してファイルを削除できます。本当に削除されるまでに遅延があっても、barは本当に空です。 barを削除するか、またはに新しいobsolete.txtを作成して、競合する心配がありません。

foo(削除しようとしているツリーのルート)を削除する途中でbar(ディレクトリ)を削除するには、同じゲームをプレイします。それをルートの親に移動し、RemoveDirectoryと呼んで、それから最終的に削除されることを知ってメリーに沿って進んでください。

+0

私はこれがディレクトリでは動作しないと信じています。親ディレクトリに書き込む権利があるとは必ずしも言えません。だから私はそこに移動することはできません。第二に、%TEMP%は別のドライブ上にある可能性があり、 'MoveFile'はドライブ間でディレクトリを移動できないため、%TEMP%に移動することもできません。 – RobertK

+0

@RobertK、あなたが 'foo'を削除する権利を持っていれば、必ず' foo'の親に書き込む権利はありませんか?階層内のすべてが同じ所有者に対して請求されていない場合でも、クォータの問題に遭遇する可能性がありますが、それは非常に起こりにくいようです。 ( '%TEMP'は別のドライブ上にある可能性がありますが、それは問題です。) –

0

可能なオプション:

  • はディレクトリを削除し、その存在をチェックし、その後
    何のハンドルが開いてなかった場合、それが削除されます。ハンドルがまだ開かれている場合は別の問題があります。必要に応じて、各存在チェック後に数ミリ秒待つことができます。


  • 内のすべてのファイルを削除してください。再作成したいとおっしゃったので、そのコンテンツを削除してください。これにより、ディレクトリ内にまだ開いているファイルやフォルダを確認することができます。

+1

' RemoveDirectory() 'はディレクトリが空でないと失敗します。 –

+0

このように、存在のチェックが成功しても(=ディレクトリがもう存在しなくても)、同じ名前のディレクトリの作成に失敗する可能性があります。 – RobertK

関連する問題