1

次の簡単なプログラムを考えてみましょう:

private static void Main(string[] args)
{
        var directoryName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Directory");

        if (Directory.Exists(directoryName))
            Directory.Delete(directoryName, true);

        Directory.CreateDirectory(directoryName);

        var stream = File.Create(Path.Combine(directoryName, "File")); //throws
        stream.Close();
}

これは、このプログラムを実行するだけで問題なく動作します。DirectoryWindowsエクスプローラーでそれを参照してから実行すると、奇妙なことが起こります。この場合、 UnautorizedAccessException を取得します"Access to the path 'C:\Users\rfurman\AppData\Roaming\Directory\File' is denied."

これがおかしい場合は、同じ条件でこれを実行します。

private static void Main(string[] args)
{
        var directoryName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Directory");

        if (Directory.Exists(directoryName))
            Directory.Delete(directoryName, true);

        var value = Directory.Exists(directoryName);

        Console.WriteLine(value);
        Console.ReadKey();
 }

このプログラムは、エクスプローラーで開いているTrue場合に印刷されます。Directory

私が知りたいのは、なぜこれが起こるのか、そしてそのような状況から身を守る方法です.

Windows 7 と .net 4 を使用しています。

4

4 に答える 4

3

これはやや重複しています: SSDドライブでの奇妙なディレクトリ削除動作

エクスプローラーは、フォルダーの削除でわずかに長い遅延を引き起こしています。ディレクトリの削除は、「厳密には」同期操作ではありません。ディレクトリは削除対象としてマークされていますが、実際の削除は少し遅れる場合があります。

私の知る限り、これは NTFS (win2k/Xp) の時代から存在しています。

于 2012-10-12T19:09:41.697 に答える
2

Directory.Deleteで内部的RemoveDirectoryに win api を使用しKernel32ます。RemoveDirectory が行うことは、「ディレクトリに削除のマークを付ける」ことです。そのディレクトリの最後のハンドルが閉じられると、ディレクトリは削除されます。これは「エクスプローラーがそのフォルダーを離れた後」を意味すると思います

私のコンピューターではこのような状況は発生しないため、テストすることはできませんが、方法があるのではないかと思います。NT ベースのシステムでは、開いているファイルやディレクトリの名前を変更できる場合があります。これが許可されている正確なケースはわかりませんが、これを使用して、ロードされた dll ファイルの名前を変更し、次のように新しいファイルを作成しました。

File.Rename(@"C:\App\test.dll", @"C:\App\test.dll");
File.Copy(@"C:\App\Update\test.dll-v1.1", @"C:\App\test.dll");

したがって、変更後のコードは次のようになります

var directoryName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Directory");

if (Directory.Exists(directoryName)) {
    var randomExt = ".random"; // generate randomly
    Directory.Move(directoryName, directoryName + randomExt)
    Directory.Delete(directoryName + randomExt, true);
}
Directory.CreateDirectory(directoryName);

var stream = File.Create(Path.Combine(directoryName, "File")); //throws
stream.Close();
于 2012-10-12T11:28:32.820 に答える
0

この問題は私も驚きました。別のクラッジである私の代替案:

    if (Directory.Exists(directoryName))
    {
        Directory.Delete(directoryName, true);
        while (Directory.Exists(directoryName))
            Thread.Sleep(100);
    }

    Directory.CreateDirectory(directoryName);
于 2013-02-28T17:16:03.547 に答える
-1

指定したディレクトリをエクスプローラーで開いている場合、Delete メソッドで削除できない場合があります。

参考:Directory.Delete メソッド

于 2012-10-09T11:15:51.660 に答える