Korzystam z .NET 3.5, próbując rekurencyjnie usunąć katalog używając:
Directory.Delete(myPath, true);
Rozumiem, że powinno to wyrzucić, jeśli pliki są w użyciu lub występuje problem z uprawnieniami, ale w przeciwnym razie powinien usunąć katalog i całą jego zawartość.
Jednak czasami otrzymuję to:
System.IO.IOException: The directory is not empty.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.Directory.DeleteHelper(String fullPath, String userPath, Boolean recursive)
at System.IO.Directory.Delete(String fullPath, String userPath, Boolean recursive)
...
Nie dziwię się, że metoda czasami rzuca, ale jestem zaskoczony otrzymaniem tego konkretnego komunikatu, gdy rekurencja jest prawdziwa. ( Wiem, że katalog nie jest pusty.)
Czy istnieje powód, dla którego widziałbym to zamiast AccessViolationException?
Odpowiedzi:
Uwaga edytora: Mimo że ta odpowiedź zawiera przydatne informacje, jest nieprawidłowa pod względem działania
Directory.Delete
. Przeczytaj komentarze do tej odpowiedzi i inne odpowiedzi na to pytanie.Wcześniej napotkałem ten problem.
Przyczyną problemu jest to, że ta funkcja nie usuwa plików znajdujących się w strukturze katalogów. Musisz więc stworzyć funkcję, która usuwa wszystkie pliki w strukturze katalogów, a następnie wszystkie katalogi przed usunięciem samego katalogu. Wiem, że jest to sprzeczne z drugim parametrem, ale jest to znacznie bezpieczniejsze podejście. Ponadto prawdopodobnie będziesz chciał usunąć atrybuty dostępu TYLKO DO CZYTANIA z plików bezpośrednio przed ich usunięciem. W przeciwnym razie powstanie wyjątek.
Po prostu włóż ten kod do swojego projektu.
Również dla mnie osobiście dodaję ograniczenie w obszarach komputera, które można usunąć, ponieważ chcesz, aby ktoś wywoływał tę funkcję na
C:\WINDOWS (%WinDir%)
lubC:\
.źródło
Directory.Delete(path, true)
nie usuwa plików, jest nieprawidłowe. Zobacz MSDN msdn.microsoft.com/en-us/library/fxeahc5f.aspxDirectory.Delete(string,bool)
zawiedzie, coś jest zablokowane lub niewłaściwie dopuszczone i nie ma jednego rozmiaru pasującego do wszystkich rozwiązań takiego problemu. Ludzie muszą rozwiązać ten problem w swoim kontekście, a my nie powinniśmy robić wielkiego włochatego rzutu każdym pomysłem na problem (z ponownymi próbami i połykaniem wyjątków) i mieć nadzieję na dobry wynik.Jeśli próbujesz rekurencyjnie usunąć katalog,
a
a kataloga\b
jest otwarty w Eksploratorze,b
zostanie usunięty, ale pojawi się błąd „katalog nie jest pusty”,a
mimo że jest pusty, gdy idziesz szukać. Bieżący katalog dowolnej aplikacji (w tym Eksploratora) zachowuje uchwyt do katalogu . Gdy zadzwoniszDirectory.Delete(true)
, usuwa się od dołu do góry:,b
a następniea
. Jeślib
jest otwarty w Eksploratorze, Eksplorator wykryje usunięcieb
, zmieni katalog do górycd ..
i wyczyści otwarte uchwyty. Ponieważ system plików działa asynchronicznie, plikDirectory.Delete
operacja kończy się niepowodzeniem z powodu konfliktu z Eksploratorem.Niekompletne rozwiązanie
Pierwotnie opublikowałem następujące rozwiązanie, z myślą o przerwaniu bieżącego wątku, aby dać czas Eksploratorowi na zwolnienie uchwytu katalogu.
Ale działa to tylko wtedy, gdy otwarty katalog jest bezpośrednim dzieckiem potomka usuwanego katalogu. Jeśli
a\b\c\d
jest otwarty w Eksploratorze i używasz goa
, ta technika zawiedzie po usunięciud
ic
.Nieco lepsze rozwiązanie
Ta metoda obsłuży usuwanie głębokiej struktury katalogów, nawet jeśli jeden z katalogów niższego poziomu jest otwarty w Eksploratorze.
Pomimo dodatkowej pracy polegającej na samodzielnym wykonywaniu rekurencji nadal musimy sobie z tym poradzić
UnauthorizedAccessException
które mogą wystąpić po drodze. Nie jest jasne, czy pierwsza próba usunięcia toruje drogę drugiej, udanej, czy tylko opóźnienie czasowe wprowadzone przez zgłoszenie wyjątku, który pozwala systemowi plików na nadrobienie zaległości.Możesz być w stanie zmniejszyć liczbę wyjątków zgłaszanych i wychwytywanych w typowych warunkach, dodając a
Thread.Sleep(0)
na początkutry
bloku. Ponadto istnieje ryzyko, że pod dużym obciążeniem systemu możesz przelecieć przez obieDirectory.Delete
próby i zawieść. Rozważ to rozwiązanie jako punkt wyjścia do bardziej niezawodnego usuwania rekurencyjnego.Ogólna odpowiedź
To rozwiązanie dotyczy tylko osobliwości interakcji z Eksploratorem Windows. Jeśli chcesz mieć solidną operację usuwania, pamiętaj, że wszystko (skaner antywirusowy, cokolwiek) może mieć otwarty uchwyt do tego, co próbujesz usunąć w dowolnym momencie. Więc musisz spróbować ponownie później. To, ile później i ile razy spróbujesz, zależy od tego, jak ważne jest usunięcie obiektu. Jak wskazuje MSDN ,
To niewinne oświadczenie, zawierające jedynie link do dokumentacji referencyjnej NTFS, powinno sprawić, że twoje włosy staną na nogi.
( Edycja : Dużo. Ta odpowiedź pierwotnie miała tylko pierwsze, niepełne rozwiązanie).
źródło
catch
blok jest wykonywany (tymczasem Explorer nadal zwalnia katalog, ponieważ nie wysłano żadnego polecenia informującego go, aby tego nie robił). Wezwanie doThread.Sleep(0)
może, ale nie musi być konieczne, ponieważcatch
blok dał już systemowi trochę więcej czasu, ale zapewnia dodatkowe bezpieczeństwo za niewielką cenę. NastępnieDelete
jest wywoływany, a katalog jest już zwolniony.Zanim przejdziesz dalej, sprawdź następujące przyczyny, które są pod twoją kontrolą:
W przeciwnym razie sprawdź następujące uzasadnione powody, na które nie masz wpływu:
Jeśli którykolwiek z powyższych problemów stanowi problem, powinieneś zrozumieć, dlaczego tak się dzieje, zanim spróbujesz poprawić kod usuwania. Czy Twoja aplikacja powinna usuwać pliki tylko do odczytu lub niedostępne? Kto tak je oznaczył i dlaczego?
Po wykluczeniu powyższych przyczyn nadal istnieje możliwość fałszywych awarii. Usunięcie nie powiedzie się, jeśli ktoś będzie trzymał uchwyt usuwanego pliku lub folderu, a istnieje wiele powodów, dla których ktoś może wyliczyć folder lub odczytać jego pliki:
Ogólne podejście do radzenia sobie z fałszywymi niepowodzeniami polega na wielokrotnym próbowaniu, przerywaniu między próbami. Oczywiście nie chcesz próbować wiecznie, więc powinieneś poddać się po pewnej liczbie prób i albo rzucić wyjątek, albo zignorować błąd. Lubię to:
Moim zdaniem takiego pomocnika należy używać do wszystkich operacji usuwania, ponieważ fałszywe niepowodzenia są zawsze możliwe. NALEŻY DOSTOSOWAĆ TEN KOD DO SWOJEJ PRZYPADKU, a nie tylko na ślepo kopiować.
Miałem fałszywe awarie wewnętrznego folderu danych generowanego przez moją aplikację, zlokalizowanego pod% LocalAppData%, więc moja analiza wygląda następująco:
Folder jest kontrolowany wyłącznie przez moją aplikację, a użytkownik nie ma uzasadnionego powodu, aby oznaczać rzeczy jako tylko do odczytu lub niedostępne w tym folderze, więc nie próbuję obsługiwać tej sprawy.
Nie ma tam żadnych cennych rzeczy stworzonych przez użytkowników, więc nie ma ryzyka wymuszonego usunięcia czegoś przez pomyłkę.
Będąc wewnętrznym folderem danych, nie oczekuję, że będzie on otwarty w Eksploratorze, a przynajmniej nie czuję potrzeby szczegółowej obsługi sprawy (tj. Dobrze sobie radzę z tą sprawą poprzez wsparcie).
Jeśli wszystkie próby zakończą się niepowodzeniem, zdecyduję się zignorować błąd. W najgorszym przypadku aplikacja nie rozpakowuje niektórych nowszych zasobów, ulega awarii i monituje użytkownika o kontakt z pomocą techniczną, co jest dla mnie dopuszczalne, o ile nie zdarza się to często. Lub, jeśli aplikacja się nie zawiesi, pozostawi po sobie trochę starych danych, co znowu jest dla mnie akceptowalne.
Wybieram ograniczenie ponownych prób do 500ms (50 * 10). Jest to arbitralny próg, który działa w praktyce; Chciałem, aby próg był wystarczająco krótki, aby użytkownicy nie zabili aplikacji, sądząc, że przestała ona odpowiadać. Z drugiej strony, pół sekundy to dużo czasu dla sprawcy na zakończenie przetwarzania mojego folderu. Sądząc po innych odpowiedziach SO, które czasami wydają się nawet
Sleep(0)
do zaakceptowania, bardzo niewielu użytkowników kiedykolwiek doświadczy więcej niż jednej próby.Próbuję co 50 ms, co jest kolejną dowolną liczbą. Wydaje mi się, że jeśli plik jest przetwarzany (indeksowany, sprawdzany), gdy próbuję go usunąć, 50 ms to właściwy czas, aby oczekiwać zakończenia przetwarzania w moim przypadku. Ponadto 50 ms jest wystarczająco małe, aby nie spowodować zauważalnego spowolnienia; znowu
Sleep(0)
wydaje się wystarczające w wielu przypadkach, więc nie chcemy zbytnio opóźniać.Kod próbuje powtórzyć wyjątki we / wy. Zwykle nie oczekuję żadnych wyjątków w dostępie do% LocalAppData%, więc wybrałem prostotę i zaakceptowałem ryzyko 500 ms opóźnienia w przypadku wystąpienia uzasadnionego wyjątku. Nie chciałem też znaleźć sposobu na wykrycie dokładnego wyjątku, na którym chcę spróbować ponownie.
źródło
Directory.Exists
strażnik by to zrobił nie rozwiązuj tego.]Nowoczesna odpowiedź asynchroniczna
Przyjęta odpowiedź jest po prostu błędna, może działać dla niektórych osób, ponieważ czas potrzebny na pobranie plików z dysku uwalnia wszystko, co je blokowało. Faktem jest, że dzieje się tak, ponieważ pliki są blokowane przez inny proces / strumień / akcję. Inne odpowiedzi używają
Thread.Sleep
(Fuj), aby ponownie spróbować usunąć katalog po pewnym czasie. To pytanie wymaga ponownej odpowiedzi z bardziej nowoczesną odpowiedzią.Testy jednostkowe
Testy te pokazują przykład, w jaki sposób zablokowany plik może spowodować
Directory.Delete
awarię i jakTryDeleteDirectory
powyższa metoda rozwiązuje problem.źródło
Thread.Sleep
których powinieneś dziś unikać i zamiast tego używajasync
/await
withTask.Delay
. To zrozumiałe, to bardzo stare pytanie.BC36943 'Await' cannot be used inside a 'Catch' statement, a 'Finally' statement, or a 'SyncLock' statement.
if (!Directory.Exists(directoryPath)) { return true; } await Task.Delay(millisecondsDelay);
aby poczekać, aż katalog naprawdę zniknieJedną ważną rzeczą, o której należy wspomnieć (dodałem to jako komentarz, ale nie wolno mi), że zachowanie przeciążenia zmieniło się z .NET 3.5 na .NET 4.0.
Począwszy od .NET 4.0 usuwa pliki w samym folderze, ale NIE w 3.5. Można to również zobaczyć w dokumentacji MSDN.
.NET 4.0
.NET 3.5
źródło
Miałem ten sam problem za Delphi. W rezultacie moja aplikacja blokowała katalog, który chciałem usunąć. Jakoś katalog został zablokowany, kiedy do niego pisałem (niektóre pliki tymczasowe).
Złap 22 polegał na tym, że przed usunięciem zrobiłem prosty katalog zmian do jego rodzica.
źródło
Dziwi mnie, że nikt nie pomyślał o tej prostej nierekurencyjnej metodzie, która może usuwać katalogi zawierające pliki tylko do odczytu, bez potrzeby zmiany atrybutu tylko do odczytu każdego z nich.
(Zmień trochę, aby nie uruchamiać na chwilę okna cmd, które jest dostępne w całym Internecie)
źródło
Możesz odtworzyć błąd, uruchamiając:
Podczas próby usunięcia katalogu „b” zgłasza wyjątek IOException „Katalog nie jest pusty”. To głupie, ponieważ właśnie usunęliśmy katalog „c”.
Z mojego zrozumienia wynika, że katalog „c” jest stemplowany jako usunięty. Ale usunięcie nie jest jeszcze zatwierdzone w systemie. System ma odpowiedź, że zadanie zostało wykonane, podczas gdy w rzeczywistości jest nadal przetwarzane. System prawdopodobnie czeka, aż eksplorator plików skupi się na katalogu nadrzędnym, aby zatwierdzić usunięcie.
Jeśli spojrzysz na kod źródłowy funkcji Delete ( http://referencesource.microsoft.com/#mscorlib/system/io/directory.cs ), zobaczysz, że używa natywnej funkcji Win32Native.RemoveDirectory. Zwrócono uwagę na to, że nie trzeba czekać:
( http://msdn.microsoft.com/en-us/library/windows/desktop/aa365488(v=vs.85).aspx )
Uśpij i spróbuj ponownie. Por. Rozwiązanie ryascl.
źródło
Miałem te dziwne problemy z uprawnieniami podczas usuwania katalogów profilu użytkownika (w C: \ Documents and Settings), mimo że mogłem to zrobić w powłoce Eksploratora.
Nie ma dla mnie sensu, co robi operacja „pliku” na katalogu, ale wiem, że to działa i to mi wystarczy!
źródło
Ta odpowiedź jest oparta na: https://stackoverflow.com/a/1703799/184528 . Różnica w stosunku do mojego kodu polega na tym, że rekursywne usuwanie wielu podkatalogów i plików następuje tylko wtedy, gdy jest to konieczne.
źródło
UnauthorizedAccessException
? Po prostu znowu rzuciłby. I ponownie. I znowu ... Ponieważ za każdym razem będzie przechodzić docatch
i wywoływać funkcję ponownie. AThread.Sleep(0);
nie zmienia twoich uprawnień. W tym momencie powinien po prostu zapisać błąd i zakończyć się niepowodzeniem. Pętla ta będzie kontynuowana tak długo, jak długo (pod-) katalog będzie otwarty - nie zamyka go programowo. Czy jesteśmy gotowi na to pozwolić, dopóki te rzeczy pozostaną otwarte? Czy jest lepszy sposób?UnauthorizedAccessException
, będzie próbował ręcznie ręcznie usunąć każdy plik. Więc nadal robi postępy, przechodząc do struktury katalogów. Tak, potencjalnie każdy plik i katalog zgłosi ten sam wyjątek, ale może to również wystąpić po prostu dlatego, że program explorer trzyma do niego uchwyt (patrz stackoverflow.com/a/1703799/184528 ). Zmienię „tryAgain” na „secondTry” aby było bardziej jasne.Process.Kill()
na dowolnym procesie, przez który plik może zostać zablokowany i usunąć pliki. Problem, na który napotykam, polega na usuwaniu katalogu, w którym jeden z tych plików był nadal otwarty (patrz stackoverflow.com/questions/41841590/... ). Wracając przez tę pętlę, bez względu na to, co jeszcze zrobi, jeśli zrobiDirectory.Delete()
to ponownie w tym folderze, nadal zawiedzie, jeśli tego uchwytu nie można zwolnić.UnauthorizedAccessException
stało, odkąd usuwanie plików (zakładając, że było to nawet dozwolone, ponieważ aby dostać się do tego kodu, nie powiodło sięDirectory.Delete()
) nie magicznie daje ci pozwolenia na usunięcie katalogu.Żadne z powyższych rozwiązań nie działało dla mnie dobrze. Skończyło się na użyciu edytowanej wersji rozwiązania @ryascl, jak poniżej:
źródło
Czy to możliwe, że masz wyścig, w którym inny wątek lub proces dodaje pliki do katalogu:
Sekwencja będzie wyglądać następująco:
Proces Deleter A:
Jeśli ktoś inny doda plik między 1 a 2, to może 2 rzuciłby wymieniony wyjątek?
źródło
Spędziłem kilka godzin, aby rozwiązać ten problem i inne wyjątki związane z usunięciem katalogu. To jest moje rozwiązanie
Ten kod ma małe opóźnienie, co nie jest ważne dla mojej aplikacji. Ale bądź ostrożny, opóźnienie może być dla ciebie problemem, jeśli masz wiele podkatalogów w katalogu, który chcesz usunąć.
źródło
Rekurencyjne usuwanie katalogu, który nie usuwa plików, jest z pewnością nieoczekiwane. Moja poprawka do tego:
Wystąpiły przypadki, w których to pomogło, ale ogólnie Directory.Delete usuwa pliki wewnątrz katalogów po rekurencyjnym usuwaniu Wystąpiły udokumentowano w msdn .
Od czasu do czasu spotykam się z tym nieregularnym zachowaniem również jako użytkownik Eksploratora Windows: Czasami nie mogę usunąć folderu (wydaje się, że nonsensowny komunikat to „odmowa dostępu”), ale kiedy przechodzę do szczegółów i usuwam dolne elementy, mogę następnie usunąć górną przedmioty również. Sądzę więc, że powyższy kod dotyczy anomalii systemu operacyjnego - nie problemu biblioteki podstawowej.
źródło
Katalog lub plik w nim jest zablokowany i nie można go usunąć. Znajdź winowajcę, który go blokuje, i sprawdź, czy możesz go wyeliminować.
źródło
Wygląda na to, że wybranie ścieżki lub podfolderu w Eksploratorze Windows wystarczy, aby zablokować pojedyncze wykonanie Directory.Delete (ścieżka, prawda), zgłaszając wyjątek IOException, jak opisano powyżej, i umiera zamiast uruchamiać Eksploratora Windows do folderu nadrzędnego i postępować jak spodziewany.
źródło
Miałem dzisiaj ten problem. Działo się tak, ponieważ miałem eksploratora Windows otwartego na katalog, który próbował zostać usunięty, powodując niepowodzenie wywołania rekurencyjnego, a tym samym wyjątek IOException. Upewnij się, że nie ma otwartych uchwytów do katalogu.
Ponadto MSDN jest jasne, że nie musisz pisać własnych wniosków: http://msdn.microsoft.com/en-us/library/fxeahc5f.aspx
źródło
Miałem ten sam problem z Windows Workflow Foundation na serwerze kompilacji z TFS2012. Wewnętrznie przepływ pracy o nazwie Directory.Delete () z flagą rekurencyjną ustawioną na true. W naszym przypadku wydaje się, że jest związany z siecią.
Usuwaliśmy binarny folder upuszczania z udziału sieciowego przed ponownym utworzeniem i ponownym zapełnieniem go najnowszymi plikami binarnymi. Każda inna kompilacja zawiedzie. Podczas otwierania folderu upuszczania po nieudanej kompilacji folder był pusty, co wskazuje, że każdy aspekt wywołania Directory.Delete () był udany, z wyjątkiem usunięcia faktycznie katalogu.
Problem wydaje się być spowodowany asynchroniczną naturą komunikacji plików sieciowych. Serwer kompilacji powiedział serwerowi plików, aby usunął wszystkie pliki, a serwer plików zgłosił, że tak, mimo że nie został całkowicie ukończony. Następnie serwer kompilacji zażądał usunięcia katalogu, a serwer plików odrzucił żądanie, ponieważ nie zakończył całkowicie usuwania plików.
Dwa możliwe rozwiązania w naszym przypadku:
Ta ostatnia metoda jest szybka i brudna, ale wydaje się, że załatwia sprawę.
źródło
Wynika to z FileChangesNotifications.
Dzieje się tak od czasu ASP.NET 2.0. Usunięty folder w aplikacji zostanie ponownie uruchomiony . Możesz to zobaczyć sam, korzystając z monitorowania kondycji ASP.NET .
Po prostu dodaj ten kod do swojego web.config / configuration / system.web:
Następnie sprawdź
Windows Log -> Application
. Co się dzieje:Po usunięciu folderu, jeśli istnieje jakiś podfolder,
Delete(path, true)
najpierw usuwa podfolder. Wystarczy, aby FileChangesMonitor wiedział o usuwaniu i wyłączaniu aplikacji. Tymczasem twój katalog główny nie został jeszcze usunięty. To jest wydarzenie z Log:Delete()
nie zakończył pracy, a ponieważ aplikacja się wyłącza, pojawia się wyjątek:Jeśli nie masz żadnych podfolderów w usuwanym folderze, Delete () po prostu usuwa wszystkie pliki i ten folder, aplikacja również jest restartowana, ale nie otrzymujesz żadnych wyjątków , ponieważ ponowne uruchomienie aplikacji niczego nie przerywa. Ale nadal tracisz wszystkie sesje w toku, aplikacja nie odpowiada na żądania przy ponownym uruchomieniu itp.
Co teraz?
Istnieją pewne obejścia i poprawki, aby wyłączyć to zachowanie, łączenie katalogów , wyłączanie FCN za pomocą rejestru , zatrzymywanie FileChangesMonitor za pomocą Reflection (ponieważ nie ma metody narażonej) , ale nie wszystkie wydają się mieć rację, ponieważ FCN jest dostępny dla powód. Dba o strukturę Twojej aplikacji , która nie jest strukturą Twoich danych . Krótka odpowiedź brzmi: umieść foldery, które chcesz usunąć, poza aplikacją. FileChangesMonitor nie otrzyma żadnych powiadomień, a aplikacja nie będzie ponownie uruchamiana za każdym razem. Nie dostaniesz żadnych wyjątków. Aby były widoczne z Internetu, istnieją dwa sposoby:
Utwórz kontroler, który obsługuje połączenia przychodzące, a następnie odsyła pliki, odczytując z folderu poza aplikacją (poza wwwroot).
Jeśli Twój projekt jest duży, a wydajność jest najważniejsza, skonfiguruj osobny mały i szybki serwer WWW do obsługi zawartości statycznej. W ten sposób IIS pozostawi swoją konkretną pracę. Może to być ten sam komputer (mongoose dla Windows) lub inny komputer (nginx dla Linux). Dobra wiadomość jest taka, że nie musisz płacić dodatkowej licencji Microsoft, aby skonfigurować statyczny serwer treści na Linuksie.
Mam nadzieję że to pomoże.
źródło
Jak wspomniano powyżej, „zaakceptowane” rozwiązanie zawodzi przy ponownej analizie punktów - ale ludzie nadal go oceniają (???). Istnieje o wiele krótsze rozwiązanie, które poprawnie powiela funkcjonalność:
Wiem, że nie obsługuje przypadków uprawnień wymienionych później, ale dla wszystkich zamiarów i celów FAR LEPIEJ zapewnia oczekiwaną funkcjonalność oryginalnego katalogu / stock.Delete () - oraz z dużo mniejszym kodem .
Możesz bezpiecznie kontynuować przetwarzanie, ponieważ stary katalog nie będzie przeszkadzał ... nawet jeśli nie zniknie, ponieważ „system plików wciąż nadrabia zaległości” (lub jakąkolwiek wymówkę, jaką MS podało, by zapewnić zepsutą funkcję) .
Jako korzyść, jeśli wiesz, że twój katalog docelowy jest duży / głęboki i nie chcesz czekać (lub zawracać sobie głowy wyjątkami), ostatni wiersz można zastąpić:
Nadal możesz bezpiecznie kontynuować pracę.
źródło
\\server\C$\dir
i udało się\\server\C$asf.yuw
. W rezultacie otrzymałem błąd naDirectory.Move()
-Source and destination path must have identical roots. Move will not work across volumes.
Działało dobrze, kiedy użyłem kodu Pete'a Z WYJĄTKIEM ani nie obsługuje, gdy są zablokowane pliki lub otwarte katalogi - więc nigdy nie dostaje się doThreadPool
polecenia.Ten problem może pojawić się w systemie Windows, gdy w katalogu (lub w dowolnym podkatalogu) znajdują się pliki, których długość ścieżki jest większa niż 260 symboli.
W takich przypadkach musisz usunąć
\\\\?\C:\mydir
zamiastC:\mydir
. O limicie 260 symboli możesz przeczytać tutaj .źródło
Rozwiązałem tę tysiącletnią technikę (możesz opuścić Nić, sam spać w haczyku)
źródło
Jeśli bieżący katalog aplikacji (lub innej aplikacji) to ten, który próbujesz usunąć, nie będzie to błąd naruszenia zasad dostępu, ale katalog nie będzie pusty. Upewnij się, że nie jest to twoja aplikacja, zmieniając bieżący katalog; Upewnij się również, że katalog nie jest otwarty w jakimś innym programie (np. Word, Excel, Total Commander itp.). Większość programów przejdzie do katalogu ostatnio otwartego pliku, co spowodowałoby to.
źródło
w przypadku plików sieciowych Directory.DeleteHelper (rekursywny: = prawda) może powodować wyjątek IOException, który jest spowodowany opóźnieniem usunięcia pliku
źródło
Myślę, że istnieje jakiś plik otwarty przez jakiś strumień, o którym nie wiesz, że miałem ten sam problem i rozwiązałem go, zamykając wszystkie strumienie wskazujące katalog, który chciałem usunąć.
źródło
Ten błąd występuje, jeśli jakikolwiek plik lub katalog zostanie uznany za używany. Jest to błąd wprowadzający w błąd. Sprawdź, czy masz jakieś okna eksploratora lub okna wiersza poleceń otwarte dla dowolnego katalogu w drzewie lub programu, który używa pliku w tym drzewie.
źródło
Rozwiązałem jeden możliwy przypadek podanego problemu, gdy metody były asynchronizowane i kodowane w następujący sposób:
Z tym:
Wniosek? Istnieje pewien asynchroniczny aspekt pozbycia się uchwytu używanego do sprawdzania istnienia, z którym Microsoft nie był w stanie rozmawiać. To tak, jakby metoda asynchroniczna w instrukcji if miała instrukcję if działającą jak instrukcja using.
źródło
Nie musisz tworzyć dodatkowych metod rekurencyjności ani usuwać plików w folderze dodatkowym. Wszystko to odbywa się automatycznie przez telefon
Szczegóły są tutaj .
Coś takiego działa całkiem dobrze:
przekazanie wartości true jako zmiennej w celu usunięcia metody spowoduje usunięcie również plików podrzędnych i podfolderów z plikami.
źródło
Żadna z powyższych odpowiedzi nie działała dla mnie. Wygląda na to, że użycie mojej aplikacji
DirectoryInfo
do katalogu docelowego spowodowało, że pozostała zablokowana.Wymuszanie wyrzucania elementów bezużytecznych rozwiązało problem, ale nie od razu. Kilka prób usunięcia w razie potrzeby.
Zwróć uwagę na
Directory.Exists
to, że może zniknąć po wyjątku. Nie wiem, dlaczego usunięcie było dla mnie opóźnione (Windows 7 SP1)źródło
GC.Collect
to a) po prostu zła rada ib) niewystarczająco powszechna ogólna przyczyna zablokowanych reżimów, aby zasługiwać na włączenie tutaj. Po prostu wybierz jedną z pozostałych i nie siej więcej zamieszania w umysłach niewinnych czytelnikówusing
oświadczeniem, a następnie:using (DirectoryInfo di = new DirectoryInfo(@"c:\MyDir")) { for (int attempts = 0; attempts < 10; attempts++) { try { if (di.Exists(folder)) { Directory.Delete(folder, true); } return; } catch (IOException e) { Thread.Sleep(1000); } } }
dodaj true w drugim param.
Usunie wszystko.
źródło