Dizini özyinelemeli olarak silmeye çalışıyorsanız a
ve dizin a\b
Explorer'da açıksa b
silinir, ancak a
gittiğinizde ve baktığınızda boş olsa bile 'dizin boş değil' hatasını alırsınız . Herhangi bir uygulamanın (Explorer dahil) geçerli dizini , dizin için bir tanıtıcı tutar . Aradığınızda Directory.Delete(true)
, aşağıdan yukarıya siler:, b
sonra a
. Eğer b
Explorer'da açıktır Explorer silinmesini algılar b
yukarı değişim dizini cd ..
ve açık kolları temizlemek. Dosya sistemi zaman uyumsuz olarak çalıştığından, Directory.Delete
Explorer ile çakışmalar nedeniyle işlem başarısız olur.
Eksik çözüm
Başlangıçta Explorer'ın dizin tanıtıcısını serbest bırakması için izin vermek için geçerli iş parçacığını kesme fikriyle aşağıdaki çözümü gönderdim.
// incomplete!
try
{
Directory.Delete(path, true);
}
catch (IOException)
{
Thread.Sleep(0);
Directory.Delete(path, true);
}
Ancak bu yalnızca açık dizin, sildiğiniz dizinin hemen alt öğesi ise işe yarar . Eğer a\b\c\d
Explorer'da açıktır ve bu konuda kullanmak a
, bu teknik silindikten sonra başarısız olur d
ve c
.
Biraz daha iyi bir çözüm
Bu yöntem, alt düzey dizinlerden biri Gezgin'de açık olsa bile derin bir dizin yapısının silinmesini işleyecektir.
/// <summary>
/// Depth-first recursive delete, with handling for descendant
/// directories open in Windows Explorer.
/// </summary>
public static void DeleteDirectory(string path)
{
foreach (string directory in Directory.GetDirectories(path))
{
DeleteDirectory(directory);
}
try
{
Directory.Delete(path, true);
}
catch (IOException)
{
Directory.Delete(path, true);
}
catch (UnauthorizedAccessException)
{
Directory.Delete(path, true);
}
}
Tek başına tekrarlama çalışmalarına rağmen, yine de UnauthorizedAccessException
yol boyunca meydana gelebilecek olanı ele almalıyız . İlk silme girişiminin ikinci, başarılı olana yol açıp açmadığı veya sadece dosya sisteminin yakalanmasına izin veren bir istisna atma / yakalama tarafından getirilen zamanlama gecikmesi olup olmadığı açık değildir.
Bloğun Thread.Sleep(0)
başına a ekleyerek tipik koşullar altında atılan ve yakalanan istisnaların sayısını azaltabilirsiniz try
. Ayrıca, ağır sistem yükü altında, her iki Directory.Delete
denemeden de geçip başarısız olma riski vardır . Bu çözümü daha sağlam yinelemeli silme için bir başlangıç noktası olarak düşünün.
Genel cevap
Bu çözüm yalnızca Windows Gezgini ile etkileşimin özelliklerini ele alır. Kaya gibi sağlam bir silme işlemi istiyorsanız, akılda tutulması gereken bir şey, herhangi bir şeyin (virüs tarayıcı, ne olursa olsun), silmeye çalıştığınız şeyin herhangi bir zamanda açık bir tutamağı olabileceğidir. Bu yüzden daha sonra tekrar denemek zorundasınız. Ne kadar sonra ve kaç kez denediğiniz, nesnenin silinmesinin ne kadar önemli olduğuna bağlıdır. As MSDN gösterir ,
Sağlam dosya yineleme kodu, dosya sisteminin birçok karmaşıklığını dikkate almalıdır.
Yalnızca NTFS başvuru belgelerine bir bağlantıyla sağlanan bu masum ifade, saçlarınızı dik tutmalıdır.
( Düzenleme : Çok. Bu cevap başlangıçta sadece tamamlanmamış ilk çözüme sahipti.)