Envoyer à la Corbeille proprement en vb.net

Résolu
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 - 16 sept. 2011 à 22:16
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 - 18 sept. 2011 à 15:37
Bonjour,

Je cherche à envoyer un fichier à la corbeille en vb.net mais sans message dans déboguer... Actuellement, je fais :

 ' Sppression => corbeille
        Try
            My.Computer.FileSystem.DeleteFile(ShosenFile, Microsoft.VisualBasic.FileIO.UIOption.AllDialogs, Microsoft.VisualBasic.FileIO.RecycleOption.SendToRecycleBin, Microsoft.VisualBasic.FileIO.UICancelOption.ThrowException)
        Catch ex As OperationCanceledException
            Exit Sub
        End Try


En fait, tout va bien si l'utilisateur dit OUI. S'il choisit NON, alors j'ai un message "OperationCanceledException" non géré. D'où l'intérêt du Catch qui évite le blocage. Mais comment faire plus propre ? J'ai beau chercher sur internet, je n'ai pas trouvé de code qui traite vraiment ce problème.

Amicalement,
Us.

17 réponses

PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
18 sept. 2011 à 10:10
ici le "delete" échoue à la demande du développeur, sur l'annulation de l'utilisateur, et "deletefile" ne propose de le faire savoir que par une exception (dernier paramètre), qu'il faut donc "attraper" (catch) et gérer...
l'erreur pourrait être autre : le fichier à supprimer est introuvable, par exemple

mettre tout un bloc de code dans un tray catch n'est pas propre, oui, parce que... d'où vient l'erreur? quelle ligne? là on est d'accord, il faut "gérer", c'est à dire ne pas exécuter un code que l'on peut vérifier (ex : vérifier la syntaxe d'un dossier ("?", "", "/") avant de le créer, etc...)

mettre une ligne dans un try catch parce que, précisément, on choisit de déchencher une erreur, c'est ni propre ni pas propre, c'est.... normal et obligatoire, on le demande!

si cette solution ne te convient pas, il ne faut pas utiliser deletefile, mais SHFileOperation par exemple


une petite mise en pratique pour peut-être mieux comprendre ce fonctionnement d'exception? ok...


on va considérer 2 entiers (saisis par l'utilisateur), et tu veux diviser l'un par l'autre

pas de surprise, si b=0 on aura l'erreur division impossible !
    Private Sub Test
        Dim a As Integer = 10
        Dim b As Integer = 0
        Dim c As Double

        c = a / b 'ici va se déclencher ton erreur division par zéro impossible
    End Sub



si on met le code dans un try catch, même "une seule ligne", çà donne :
    Private Sub Test
        Dim a As Integer = 10
        Dim b As Integer = 0
        Dim c As Double
        Try
            c = a / b
        Catch ex As Exception
            MessageBox.Show("b ne doit pas valoir zéro")
        End Try
    End Sub


là, tout à fait d'accord avec toi : ce n'est pas propre! on gère une exception, alors qu'il n'y a rien d'exceptionnel ^^, on devrait tester :
    Private Sub Test
        Dim a As Integer = 10
        Dim b As Integer = 0
        Dim c As Double

        If b = 0 Then
            MessageBox.Show("b ne doit pas valoir zéro")
        Else
            c = a / b
        End If
    End Sub





maintenant on se place dans le contexte du framework, ou dans le contexte que TU fais une class de calculs, qui peut être ré-utilisable par d'autres développeurs
dans ce contexte tu ne sais pas ce que le développeur voudrait faire lors de cette erreur

si TU veux adopter le comportement usuel, tu ne fais rien de particulier :
'dans une nouvelle class par défaut
Public Class Class1
    Public Function Division(ByVal a As Integer, ByVal b As Integer) As Double
        Return a / b
    End Function
End Class


'dans la form
    Private Sub Test
        Dim a As Integer = 10
        Dim b As Integer = 0
        Dim c As Double
        Dim m As New Class1

        c = m.Div(a, b)
    End Sub



Il n'y a aucune gestion, TA CLASS (le framework) "plante"
or il y a bien une exception!!

dans ce même contexte, tu ne pourrais pas faire ce test ZERO dans ta classe pour afficher un messagebox... on suppose alors que tu fais le test mais ne fais rien :
    Public Function Div(ByVal a As Integer, ByVal b As Integer) As Double
        If b = 0 Then
            Return 0.0# 'ou Nothing éventuellement

        Else
            Return a / b

        End If
    End Function


c'est mieux, pas de gestion d'erreur à retardement.. mais au final ta fonction est fausse ! donc tu ne peux pas non plus !

[quote=banana32]Throw new exception("blablabla")/quote
en effet :
la solution propre, toujours dans ce contexte, est que TA CLASSE (et c'est ce que fait le framework) relève l'exception, ce n'est pas pour autant qu'il ne la "gère pas"
en application çà va donner :

Public Class Class1
    Public Enum DivZeroConstants
        ThrowException
        DoNothing
    End Enum
    Public Function Div(ByVal a As Integer, ByVal b As Integer, ByVal actionOnZero As DivZeroConstants) As Double
        If b = 0 Then
            If actionOnZero = DivZeroConstants.DoNothing Then
                Return Nothing

            Else
                'on relève à la demande de l'appelant
                Throw New DivideByZeroException()

            End If

        Else
            Return a / b

        End If
    End Function
End Class



le code est bien géré, et c'est au développeur de s'adapter...
donc toujours pareil, on va choisir de tester ou pas le ZERO avant, ou d'accepter le NOTHING, ou de demander de relever une exception, comme le fait deletefile :
    Private Sub Test
        Dim a As Integer = 10
        Dim b As Integer = 0
        Dim c As Double
        Dim d As Double
        Dim m As New Class1

        'on pourrait tester zéro mais pas besoin parce que par exemple, 
        'on n'exécute pas le reste du code si c=nothing
        c = m.Div(a, b, Class1.DivZeroConstants.DoNothing)
        If c = Nothing Then
            Console.WriteLine("Test.InstanceCalcul.Div = b vaut zéro, fin d'exécution de la procédure")
            'Exit Sub
        End If

        'on veut tester ZERO par l'exception
        Try
            d = m.Div(a, b, Class1.DivZeroConstants.ThrowException)
        Catch ex As Exception
            'on pourrait mettre cette ligne dans un log
            Console.WriteLine("ERREUR Test.InstanceCalcul.Div = {0}", ex.Message)
            'ex.message vaut "ERREUR Test.InstanceCalcul.Div = Tentative de division par zéro."
        End Try
    End Sub




je ne sais pas si ces explications sont assez claires....

tu comparais l'utilisation de Windows.Forms.DialogResult.OK pour une boite de dialogue...
la comparaison n'est pas bonne, prends plutôt (en vb6) la boite de chemin de fichier (commondial) qui prend un paramètre pour, aussi, relever une erreur en cas de "annuler", que l'on peut activer ou non, et qui renvoie ou non un chemin vide...

tu peux décider de demander une exception que tu vas gérer, ou ne pas avoir d'erreur et gérer sur le chemin vide, ou dans mon exemple sur le retour nothing de la fonction Div.

My.Computer.FileSystem.DeleteFile étant juste une procédure (pas une fonction), la manière adoptée pour avoir un résultat est de proposer une mise en place de gestion d'erreur à attraper

++
3
Utilisateur anonyme
16 sept. 2011 à 23:02
Bonsoir,

Tu as un exemple ici
Pas testé.

Bonne soirée.
0
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
16 sept. 2011 à 23:39
Bonsoir,

Oui, mais, non.

Le code que tu dis utilise directement l'API.

Et moi, je voudrais utiliser : My.Computer.FileSystem.DeleteFile(...)

C'est la réponse "Cancel" que je ne sais pas traiter proprement...


Amicalement,
Us.
0
PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
17 sept. 2011 à 00:30
salut,

euh.... quelle est la question au final?
"plus propre"... tu as le dernier argument qui définit l'action à effectuer lors du click sur "non" ("onUserCancel" = annulation de l'utilisateur)
soit tu relèves une erreur, ce qui est le cas ici (UICancelOption.ThrowException), que tu interceptes, soit tu ne fais rien (UICancelOption.DoNothing).

tu peux donc changer le flag si tu n'as rien à gérer en cas de refus, sinon c'est le catch comme tu as mis en place : tu demandes de relever une erreur, elle est relevée

ps : attention, si la configuration de la corbeille implique de ne pas avertir l'utilisateur, la boite de dialogue ne sera pas affichée non plus par ce code


++
[hr]
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
17 sept. 2011 à 00:52
Bonsoir PCPT,

Désolé, si j'explique mal. Mais, je crois tu vois juste (d'après mes recherches et ce que je comprends) quand tu dis :
soit tu relèves une erreur, ce qui est le cas ici (UICancelOption.ThrowException), que tu interceptes, soit tu ne fais rien (UICancelOption.DoNothing)


Et mon problème, c'est que je ne sais pas comment "relever l'erreur" ou "rien faire"... sans que le débogeur râle...

En d'autres termes, si j'écris seulement :
My.Computer.FileSystem.DeleteFile(ShosenFile, Microsoft.VisualBasic.FileIO.UIOption.AllDialogs, Microsoft.VisualBasic.FileIO.RecycleOption.SendToRecycleBin, Microsoft.VisualBasic.FileIO.UICancelOption.ThrowException)


Le code affiche la boite de dialogue pour envoyer le fichier à la corbeille, avec la demande de confirmation.
- Si le bouton "oui", pas de problème. Le fichier est envoyée à la corbeille, puis je ferme la "form"...
- Mais si le bouton "non"... Je code comment la suite ? Je veux seulement fermer la "form". Sachant que si je fais rien, il y a un arrêt sur l'exception OperationCanceledException... Et catch ne sert qu'à passer "outre" mais c'est pas très "propre"

Je remets l'ensemble du code, histoire de mieux me comprendre (peut-être) :
    ' Supprimer la note
    Private Sub SupprimeNote_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SupprimeNote.Click

        ' Chemin du fichier
        Dim ShosenFile As String = Me.Tag.ToString

        ' Sppression => corbeille
        Try
            My.Computer.FileSystem.DeleteFile(ShosenFile, Microsoft.VisualBasic.FileIO.UIOption.AllDialogs, Microsoft.VisualBasic.FileIO.RecycleOption.SendToRecycleBin, Microsoft.VisualBasic.FileIO.UICancelOption.ThrowException)
            ' Catch 'ex As OperationCanceledException
        Catch ex As Exception
            MessageBox.Show(ex.Message)
            Exit Sub
        End Try

        DirectCast(GetControlByName(Form1, "N" & SauveEtQuitter.Tag.ToString), Label).Text = Empty 'efface logo
        Me.Close()

    End Sub


Si tu avais une idée ou un code exemple...

Amicalement,
Us.
0
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
17 sept. 2011 à 00:58
Re,

Actuellement, j'ai le message :
"Une exception de première chance de type 'System.OperationCanceledException' s'est produite dans Microsoft.VisualBasic.dll"
dans la fenêtre d'exécution. Je voudrais ne plus l'entendre râler !

Amicalement,
Us.
0
PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
17 sept. 2011 à 07:53
selon le bout de code que tu mets çà veut dire que tu ne veux rien faire, mais ne quitter la form que si la suppression a réussi...

donc (sans tester) je mettrais :
    ' Supprimer la note
    Private Sub SupprimeNote_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SupprimeNote.Click
        Try
            My.Computer.FileSystem.DeleteFile(Me.Tag.ToString, Microsoft.VisualBasic.FileIO.UIOption.AllDialogs, Microsoft.VisualBasic.FileIO.RecycleOption.SendToRecycleBin, Microsoft.VisualBasic.FileIO.UICancelOption.ThrowException)
            DirectCast(GetControlByName(Form1, "N" & SauveEtQuitter.Tag.ToString), Label).Text = String.Empty 'efface logo
            Me.Close()
        Catch ex As Exception 'OperationCanceledException
            MessageBox.Show("Suppression annulée")
        End Try
    End Sub


nop?
0
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
17 sept. 2011 à 10:55
Bonjour,

Oui et non.

Oui, tu refais ce que le code faisait déjà, en fait. Mais mon problème n'est pas celui-là.

Si je choisi "NON" dans la boite de dialogue de la suppression, il y a une erreur générée dans la fenêtre d'exécution :
"Une exception de première chance de type 'System.OperationCanceledException' s'est produite dans Microsoft.VisualBasic.dll"
et comme je disais, j'aimerais ne plus l'entendre râler...

En d'autre termes, comment gérer proprement le choix "NON", quant on utilise
"My.Computer.FileSystem.DeleteFile(...."

Est-on obliger d'utiliser "Try, Catch" pour traiter la réponse ?

A titre de comparaison, avec MessageBox.show(....) , on test la réponse avec "Windows.Forms.DialogResult.OK" pour gérer la réponse. Avec "My.Computer..." qui dans ce cas lance la boite de dialogue standard, je recherche comment traiter la réponse (proprement), sans passer par la gestion de l'erreur . Qui justement, l'erreur est générée car la réponse n'est pas gérée !?

Voilà, j'espère être plus clair.

Amicalement,
Us.
0
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
17 sept. 2011 à 11:00
J'ai beaucoup recherché (plusieurs heures) sans trouver de réponse. En langage C#, j'ai vu peut-être un indice de réponse, mais je n'ai pas tout compris. Il semble que l'emploi de "Throw" serait nécessaire. C'est du conditionnelle. Mais, je n'arrive pas à vraiment comprendre ce qu'elle représente et comment la mettre en oeuvre.
La gestion des "Exceptions" est encore une chose un peu nébuleuse pour moi.

Amicalement,
Us.
0
Utilisateur anonyme
17 sept. 2011 à 21:36
L'exception levée "opération annulée" est là justement pour t'avertir que l'utilisateur à annulé puisque la méthode DeleteFile ne renvoie rien.
La présence d'un bloc Try Catch est donc tout à fait naturelle dans ce cas.
Bonne soirée.
0
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
17 sept. 2011 à 21:42
Bonsoir,

Tu veux dire qu'on ne peut pas traiter la réponse autrement que par l'exception...

Amicalement,
Us.
0
Utilisateur anonyme
17 sept. 2011 à 22:01
Ce serait inquiétant si rien ne se passait après avoir utilisé DeleteFile.
Nous ne saurions pas ce qu'à fait l'utilisateur qu'il clique sur oui ou non, à moins d'aller lire où à été mis ce foutu fichier (plutôt embêtant non ?)
0
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
17 sept. 2011 à 22:12
Ben, justement... Si on pouvait mieux gérer la réponse "NON" sans passer par l'exception, ce serait plus rassurant, nan ?

Amicalement,
Us.
0
Utilisateur anonyme
17 sept. 2011 à 22:29
Je jette l'éponge lol
C'est pourtant très pratique les exceptions, je dirais même qu'elles sont très utiles pour gérer des situations imprévues (DeleteFile sur un dossier protégé).
Il est même parfois nécessaire de les provoquer volontairement :
Throw new exception("blablabla")

Ce qui permet ensuite d'accéder à des blocs de codes différents au sein d'une même procédure par exemple... etc...
0
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
18 sept. 2011 à 00:15
Re,

"Il est même parfois nécessaire de les provoquer volontairement"


Quelle ironie !

Amicalement,
Us.
0
Utilisateur anonyme
18 sept. 2011 à 01:45
Je ne vois pas ou est l'ironie.
J'essayais de t'aider enfin bon...
0
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
18 sept. 2011 à 15:37
Bonjour,

banana, "quelle ironie", est évidemment un trait d'humour... Provoquer volontairement une exception, qu'alors on cherche à les éviter (en général). Tu auras compris, j'espère. C'est vrai qu'à minuit...

PCPT, ta réponse est un véritable tours guidé sur la question. Je te remercie d'avoir pris le temps d'éclairer ma lanterne. Je comprend beaucoup mieux cette gestion d'exception qui m'était obscur. Et, si je m'abuse, la conclusion à cette histoire, c'est qu'avec My.computer.deletefile... il n'y a pas d'autre moyen de connaitre la réponse de l'utilisateur qu'en gérant l'exception avec TRY CATCH. (Et par conséquent, il y aura toujours aussi un message indiquant l'exception dans la fenêtre d'exécution).

Encore une fois, merci à vous deux.

Amicalement,
Us.
0
Rejoignez-nous