View Full Version : [VB .NET] DirectoryInfo.GetDirectories(), problema accesso negato
nardellu
21-04-2009, 13:33
vi posto una parte di codice di un programma che stò realizzando:
dim path_primaria as string = "C:\users\utente\Documents"
Dim rootInfo As DirectoryInfo = New DirectoryInfo(path_primaria)
Try
For Each d As DirectoryInfo In rootInfo.GetDirectories("*.*", SearchOption.AllDirectories)
'se non sono cartelle nascoste o di sistema le inserisce nell'array
If (d.Attributes And IO.FileAttributes.Hidden) <> FileAttributes.Hidden Then
array_cartelle.Insert(a, d.FullName)
End If
a += 1
Next
Catch ex As UnauthorizedAccessException
'codice di gestione errore
Catch ex As Exception
'codice di gestione errore
End Try
si verifica il problema dell'accesso negato... cioè durante la chiamata rootInfo.GetDirectories("*.*", SearchOption.AllDirectories), se non si hanno le autorizzazioni si blocca...
ho provveduto con i catch a gestire il problema, ma il mio vero problema e che appena trova una cartella alla quale non può accedere, non continua il loop...
esempio su vista, nella cartella documents ci sono delle cartelle symboliche (video, musica, immagini ecc...) e mi si blocca li...
si può risolvere in qualche maniera? stò diventando scemo:mc: , e su google mi stò rincoglioxxxxx:D
any idea?;)
si potrebbe ovviare, oppure è un discorso morto?
ho provveduto con i catch a gestire il problema, ma il mio vero problema e che appena trova una cartella alla quale non può accedere, non continua il loop...
Per forza, hai messo tutto il For Each nel blocco Try Catch. Prova mettendo solo l'istruzione che può sollevare l'eccezione.
nardellu
21-04-2009, 14:39
Per forza, hai messo tutto il For Each nel blocco Try Catch. Prova mettendo solo l'istruzione che può sollevare l'eccezione.
scusami forse non mi sono spiegato bene...;)
l'errore di accesso negato, mi viene fuori durante l'inizio del ciclo...
anche se includo "try/catch" qui:
'se non sono cartelle nascoste o di sistema le inserisce nell'array
If (d.Attributes And IO.FileAttributes.Hidden) <> FileAttributes.Hidden Then
array_cartelle.Insert(a, d.FullName)
End If
ottengo sempre l'errore perché è a monte di tale operazione...
mi servirebbe una soluzione che prosegua il ciclo anche quando il metodo rootInfo.GetDirectories("*.*", SearchOption.AllDirectories) restituisce un eccezione, in questo caso accesso negato alla cartella xxxxxx...
Lo sai che anch'io sto avendo eccezioni di Accesso negato quando provo a cancellare o rinominare directory? :fagiano:
Ecco il mio codice:
if (Directory.Exists(this.ProfilePath[i, 1]))
{
try
{
Directory.Move(this.ProfilePath[i, 1], this.ProfilePath[i, 1] + "OLD");
}
catch (Exception Error)
{
MessageBox.Show(this.NameOfProgram + "TryToRenameFolder *** \n" + Error.Message);
}
}
dove ProfilePath è un array che contiene il percorso di una cartella all'interno di C:\Users\blablabla\AppData\Roaming\
Ho il sospetto che sia Windows Search a bloccare a volte l'accesso alla cartella.
Infatti, reiterando i tentativi di accesso, l'operazione viene conclusa con successo. Alla fine, io ho risolto così (anche se non mi piace come metodo):
TryToRenameFolder:
if (Directory.Exists(this.ProfilePath[i, 1]))
{
try
{
Directory.Move(this.ProfilePath[i, 1], this.ProfilePath[i, 1] + "OLD");
Thread.Sleep(200);
}
catch (Exception Error)
{
#if DEBUG
MessageBox.Show(this.NameOfProgram + "TryToRenameFolder *** \n" + Error.Message);
#endif
TryToRenameFolderCounter = TryToRenameFolderCounter + 1;
if (TryToRenameFolderCounter < 5)
{
goto TryToRenameFolder;
}
else MessageBox.Show("Sorry, there was an error. \n" + Error.Message);
}
}
Su internet leggevo della possibilità di utilizzare l'istruzione CopyFileA delle API Win32, naturalmente in codice non gestito, in quanto dovrebbe essere in grado di accedere anche a file/cartelle bloccate da un altro processo. E' così? :stordita:
Chiedo scusa all'autore del thread, ma credo che alla fine il problema sia praticamente lo stesso...
P.S: questo problema si verifica anche quando provo la mia applicazione in modalità Amministratore (uso Vista)
scusami forse non mi sono spiegato bene...;)
l'errore di accesso negato, mi viene fuori durante l'inizio del ciclo...
anche se includo "try/catch" qui:
'se non sono cartelle nascoste o di sistema le inserisce nell'array
If (d.Attributes And IO.FileAttributes.Hidden) <> FileAttributes.Hidden Then
array_cartelle.Insert(a, d.FullName)
End If
ottengo sempre l'errore perché è a monte di tale operazione...
mi servirebbe una soluzione che prosegua il ciclo anche quando il metodo rootInfo.GetDirectories("*.*", SearchOption.AllDirectories) restituisce un eccezione, in questo caso accesso negato alla cartella xxxxxx...
Secondo me non ne esci così. Devi crearti una funzione ricorsiva, che non usa SearchOption.AllDirectories, ma SearchOption.TopDirectoryOnly e ad ogni passaggio intercettare l'errore con Try Catch. Per il momento la vedo l'unica soluzione, ma mi riservo di provare più tardi... ;)
nardellu
21-04-2009, 15:09
alex783, ho visto ciò che hai fatto, ed anche io ho già provato la tua soluzione senza risoluzione...:D
ma io ho anche individuato il problema esatto, che ne mio caso è la presenza di cartelle simboliche (collegamenti a cartelle) nella cartella documents in c:\users\nomeutente\
ad esempio dentro documents, c'è la cartella Video, che come icona su explorer ha il simbolo del collegamento e quando la Getdirectories() ci passa sopra ottengo il famoso messaggio "accesso negato...",
infatti mi servirebbe un qualcosa che ignori tale errore e prosegua con le altre cartelle... ma a stò punto dubito che esista dati gli innumerevoli 3ds senza risoluzione che ho letto su google...
potrebbe anche andar bene un metodo ricorsivo per ottenere in un altra maniera cartelle e sottocartelle, e ficcarle dentro un array...
nardellu
21-04-2009, 17:13
Secondo me non ne esci così. Devi crearti una funzione ricorsiva, che non usa SearchOption.AllDirectories, ma SearchOption.TopDirectoryOnly e ad ogni passaggio intercettare l'errore con Try Catch. Per il momento la vedo l'unica soluzione, ma mi riservo di provare più tardi... ;)
be ho risolto alla fine... ;)
popolare l'array, e quando c'è l'eccezione rimuovere il valore...;)
'ciclo cartelle principali della cartella principale
For Each d As DirectoryInfo In rootInfo.GetDirectories("*", SearchOption.TopDirectoryOnly)
array_cartelle.Add(d.FullName)
Dim rootInfo2 As DirectoryInfo = New DirectoryInfo(d.FullName)
'scarta le cartelle di sistema e nascoste
If d.Attributes <> FileAttributes.Hidden And FileAttributes.System Then
'prova a ottenere tutte le sottocartelle
Try
For Each d2 As DirectoryInfo In rootInfo2.GetDirectories("*", SearchOption.AllDirectories)
array_cartelle.Add(d2.FullName)
Next
Catch ex As UnauthorizedAccessException
'se una directory provoca l'eccezzione di autorizzazioni rimuove dall'elenco cartelle
Dim remove_value = array_cartelle.Count - 1
MsgBox(Err.Description & " |" & remove_value)
array_cartelle.RemoveAt(remove_value
End Try
'fine if cartelle sistema/nascoste
End If
'fine ciclo cartelle principali
Next
forse si può fare ancora meglio, ma funge alla grande e non sgarra 1 directory... che sia utile a qualcuno...
Io invece l'ho fatta ricorsiva. La directory viene aggiunta all'ArrayList solo se non produce alcun errore d'accesso. Se una dir genera un'eccezione, mi ritrovo la descrizione completa di percorso dir in una ListBox... :
> ArrayList e Sub Ricorsiva :
Private arrayDirOk As ArrayList
Private Sub TrovaCartelle(ByVal cartellaTop As String)
Dim rootInfo As DirectoryInfo = New DirectoryInfo(cartellaTop)
Try
For Each D As DirectoryInfo In rootInfo.GetDirectories("*.*", SearchOption.TopDirectoryOnly)
'If ... Condizioni ...
arrayDirOk.Add(D.FullName)
'Rendo la Sub Ricorsiva
TrovaCartelle(D.FullName)
Next
Catch ex As Exception
lst_errori.Items.Add(ex.ToString())
End Try
End Sub
> Codice utilizzatore ( Button, ecc... ) :
lst_errori.Items.Clear()
Dim cartellaTop As String = "C:\"
arrayDirOk = New ArrayList
TrovaCartelle(cartellaTop)
;)
nardellu
21-04-2009, 18:22
ottimo esempio, meno codice e meno risorse utilizzate...
utilizzerò il tuo esempio grazie...;)
Giovanni G
27-07-2022, 17:31
Una ottima soluzione (in inglese) si trova qui: https://firebird-vbnet.blogspot.com/2022/06/vbnet-access-deied-to-folder-stops.html
Giovanni G
04-12-2022, 13:50
Una ottima soluzione (in inglese) si trova qui: https://firebird-vbnet.blogspot.com/2022/06/vbnet-access-deied-to-folder-stops.html
Vedo che quel link non funziona più. Questo funziona:
https://firebird-vbnet.blogspot.com/2022/12/access-denied-to-folder-problem-solved.html
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.