C#:ディレクトリの読み取りや削除ができるかどうかを確認する方法
-
05-07-2019 - |
質問
ディレクトリの束を再帰的にループします。それらの一部( D:\ $ RECYCLE.BIN \ S-1-5-20 など)は、 System.UnauthorizedAccessException
を提供します。私はそれを捕まえて先に進むことができると思いますが、前もってそれを理解したいです。
つまり、 DirectoryInfo
オブジェクトがある場合。 GetDirectories()
および場合によっては Delete()
が許可されているかどうかを確認するにはどうすればよいですか?
解決
削除する場合は、削除してから続行します(必要に応じて例外を処理します)。
削除する必要がある場合にチェックしてから削除を実行すると、ファイルシステムで競合状態になる可能性がありますが、わずかではあります。これは、ほとんどすべてのファイル/ディレクトリアクセス操作に適用されます。ほとんどのファイルシステム操作はアトミックになるように設計されており、このロジックをユーザーコードに移行すると、このアトミック性が競合し、発生する可能性のある例外を処理する必要があります。
他のヒント
次のコードを作成しました。役立つかどうかを確認してください:
//using System.IO;
//using System.Security.AccessControl;
//using System.Security.Principal;
string[] directories = Directory.GetDirectories(
Path.Combine(Environment.CurrentDirectory, @"..\.."),
"*", SearchOption.AllDirectories);
foreach (string directory in directories)
{
DirectoryInfo info = new DirectoryInfo(directory);
DirectorySecurity security = info.GetAccessControl();
Console.WriteLine(info.FullName);
foreach (FileSystemAccessRule rule in
security.GetAccessRules(true, true, typeof(NTAccount)))
{
Console.WriteLine("\tIdentityReference = {0}", rule.IdentityReference);
Console.WriteLine("\tInheritanceFlags = {0}", rule.InheritanceFlags );
Console.WriteLine("\tPropagationFlags = {0}", rule.PropagationFlags );
Console.WriteLine("\tAccessControlType = {0}", rule.AccessControlType);
Console.WriteLine("\tFileSystemRights = {0}", rule.FileSystemRights );
Console.WriteLine();
}
}
結果:
D:\Projects\ConsoleApplication1\bin IdentityReference = BUILTIN\Administrators InheritanceFlags = ContainerInherit, ObjectInherit PropagationFlags = None AccessControlType = Allow FileSystemRights = FullControl
IdentityReference
および FileSystemRights
プロパティ;おそらく、ディレクトリを削除する前に、現在のACLをそれらに対してテストする必要があります。
独自の GetDirectories()
メソッドを記述する必要があると思います。その中にあるものを再帰的に取得します。
このMicrosoft記事には、それを行う方法に関する優れた記事があります。作業して、クリーンアップして汎用リストを使用し、ソリューションに適合させることができます。
簡単に言えば、System.IO.Directory.GetDirectories()は、これらの例外の1つを取得するたびに失敗します。
おおまかにこのようなコード(上記からコピー)で開始できます
List<String> directories = new List<String>();
void DirSearch(string sDir)
{
try
{
foreach (string d in Directory.GetDirectories(sDir))
{
//foreach (string f in Directory.GetFiles(d, txtFile.Text))
//{
//
//}
// use this to search for files recursivly.
directories.Add(d);
DirSearch(d);
}
}
catch (System.Exception excpt)
{
Console.WriteLine(excpt.Message);
}
}
ディレクトリのリストを取得したら、その上で操作を実行できます。一部のmodでは、上記の方法により、リスト内のすべての項目に対する読み取り権限が確保されます。
問題を解決しようとしたときにこれを見つけました...
関連しているようですが、かなりメンテナンスされていないコード、私はそれを試しませんでした
よろしく
マリオ