1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    septembre 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : septembre 2009
    Messages : 72
    Points : 22
    Points
    22

    Par défaut VB.net Framework 4 - copie de dossier avec barre de progression

    Bonjour,

    Pour le compte d'une société en tant qu'auto entrepreneur, on m'a demander de créer un logiciel d'archivage de divers schémas.

    C'est quelque chose de simpliste, recherche d'archive et archivage.

    Le projet est développé en VB.net au stade Framework 4 (je sais pas si c'est bien dis mais j'imagine que les infos sont justes). Cela m'a été imposé pour une raison de Windows XP

    1. L'utilisateur saisit les infos du dossier : num de contrat, etc ... (je n'ai pas le droit de divulgué toutes les infos)

    2. Il saisit aussi les pièces à joindre (des dossiers volumineux contenant divers fichiers type PDF / word(.doc) / Word(.docx) / JPG / BMP).

    3. Il clic sur archiver et la copie commence.

    4. Si la copie est ok ajout dans la base de donnée sinon suppression des résidus.

    Je coince au numéro 3 ...

    Je voudrais faire quelque chose de propre avec une barre de progression.

    A la place pour l'instant j'ai un bricolage pour ne pas être bloquer sur le reste mais je voudrais palier à ce problème.

    Mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     
    MkDir(Application.StartupPath & "\archives\" & archive.ANUM & " " & archive.ANAME & " " & archive.AVERSION)
     
    copyreturn = DirectoryCopy(archive.ARoot, Application.StartupPath & "\archives\" & archive.ANUM & " " archive.ANAME & " " & archive.AVERSION & "\", True)
    C'est pas vraiment terrible et très simpliste pour plusieurs raison :
    - L'application ce fige le temps de la copie
    - L'application n'affiche pas de progression

    Je n'en suis plus à mon coup d'essai, mais le fait qu'on m'est imposé le vb.net comme langage m'handicape un peu car je ne le connais que peu.

    Si quelqu'un à une idée pour faire les choses mieux, je suis preneur.

  2. #2
    Membre éprouvé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    juillet 2005
    Messages
    456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Distribution

    Informations forums :
    Inscription : juillet 2005
    Messages : 456
    Points : 1 159
    Points
    1 159

    Par défaut

    Bonjour,

    Ta solution tourne autour d'un BackgroundWorker

    Bon code,
    J@ck.
    Pas de réponse par MP, merci.

    Penser au ça fait plaisir

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    septembre 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : septembre 2009
    Messages : 72
    Points : 22
    Points
    22

    Par défaut Merci

    Je vais tester ça d'ici fin de semaine, j'ai des choses en route des choses que je peux finir les yeux fermé que je vais faire en priorité,

    Je te remercie en tout cas de ta participation, ça à en effet l'air d'être une solution parfaite !

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    septembre 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : septembre 2009
    Messages : 72
    Points : 22
    Points
    22

    Par défaut Réponse tardive

    Bonjour,

    La dite solution fonctionne relativement bien, je ne peux pour l'instant en tout cas pas mettre résolu.

    Je vous explique, l'objectif est de créer un module générique implantable au travers de cette solution, et pourquoi pas d'autres à venir.

    En gros je dois avoir une fonction générique de départ dont l'entête est la suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        Public Sub StartCpy(ByVal src As String, ByVal dest As String, Optional ByRef pgb As ProgressBar = Nothing, Optional ByRef NB As String = "", Optional ByRef NBTot As String = "")
    J'ai actuellement un backgroundworker qui s'occupe de la copie et décider de coupler ça à un thread qui tant que le backgroundworker fonctionne va calculer le nombre de fichier et la taille maxi ainsi que le nombre de fichier déjà copier et la taille déjà copier.

    Jusque la pas de soucis, sauf que, bien que le paramètre soit optionnel, je n'arrive pas à l'utiliser depuis le thread que je créer plus tard afin de modifier la propriété " maximum " ainsi que la propriété " value " de la barre de progression.

    J'ai essayé de faire directement appel au controle depuis le thread, ou de passer sous forme de structure la barre de progression via un " byref " mais je ne suis pas parvenu à mes fins.

    La déclaration de mon Thread se fait dans l'entête du module comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        Public CP_Thread As Thread
    Le lancement du thread comme suit (dans la fonction StartCpy):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        CP_Thread = New Thread(AddressOf CpyThreadSub)
        CP_Thread.IsBackground = True
        CP_Thread.Start()
    Voici également le contenu de mon CpyThreadSub actuel :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     
        Public Sub CpyThreadSub()
            While backgroundWorker1.IsBusy = True
     
                Thread.Sleep(100)
                Form1.ProgressBar1.Value = CP_Value.NB
                Form1.ProgressBar1.Maximum = CP_Value.NBTot
                Form1.ProgressBar1.Refresh()
     
     
            End While
     
        End Sub
    Du fait, ce n'est que pour " essayé " déjà que j'ai fais cela, mais rien que ça, sa ne fonctionne pas.

    J'aimerais vraiment récupéré les paramètres en provenance de StartCpy(...) pour modifier la valeur, de manière à rester générique et n'avoir besoin que de l'entête de fonction pour tout faire.

    Si quelqu'un sait comment faire, je suis preneur, j'ai entendu parler de invoke mais je n'ai rien compris à ce sujet ... Les threads sont complètement différent de ce que j'en sais dans les autres langages que j'utilise :s.

  5. #5
    Membre expert
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    octobre 2008
    Messages
    1 516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : octobre 2008
    Messages : 1 516
    Points : 3 116
    Points
    3 116
    Billets dans le blog
    6

    Par défaut

    bonjour,

    Plusieurs choses :

    - utilisation des fichiers modules a proscrire, il faut préférer utiliser des classes shared ......
    - le bgw est un thread donc inutile d appeler un autre thread prealablement ou durant car sinon il risque d y avoir desynchronisation donc bugs de refresh UI ...etc.....
    - le bgw possede l event ProgressChanged donc ul faut appeler la methode reportProgress dans le DoWork afin de mettre a jour l'UI.

    Regardes MSDN pour plus d infos

    ++

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    septembre 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : septembre 2009
    Messages : 72
    Points : 22
    Points
    22

    Par défaut Suite

    Plusieurs choses :

    - utilisation des fichiers modules a proscrire, il faut préférer utiliser des classes shared ......

    -> je veux bien, j'aimerais quelques infos à ce sujet à ce moment la, quelle différence entre des module de classe et des modules de fonction classique ? j'ai utilisé ça en cours à l'époque et je n'ai pas souvenir des modules de classe.
    Aussi, tout ce que j'ai programmer d'autre est déjà en module classique et fonctionne bien, quelle difficulté pour convertir tout ça ?

    - le bgw est un thread donc inutile d appeler un autre thread prealablement ou durant car sinon il risque d y avoir desynchronisation donc bugs de refresh UI ...etc.....

    -> Jusque la ok

    - le bgw possede l event ProgressChanged donc ul faut appeler la methode reportProgress dans le DoWork afin de mettre a jour l'UI.

    -> C'est la que le soucis ce pose, la copie telle que je la fait actuellement, c'est une seule ligne de code (je rappelle que je copie soit un fichier unique, soit un dossier contenant plusieurs gros fichier).
    En ce qui concerne la copie, j'utilisais (je pensais conserver ceci) la ligne suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    copyreturn = DirectoryCopy(archive.ARoot, Application.StartupPath & "\archives\" & archive.ANUM & " " archive.ANAME & " " & archive.AVERSION & "\", True)
    Du coup, dans le même lapse de temps que le bgw je pensais déclencher un autre thread pour compter les fichiers déjà copier par cette ligne. Je me trompe peut être dans la manière de procédé.
    Sinon, j'ai bien lu et compris le ProcessChanged et ReportProgress, je m'étais basé sur le premier exemple de MSDN pour ce faire dispo ici :

    https://msdn.microsoft.com/fr-fr/lib...code-snippet-1

    C'est vrai qu'en y repensant à ce niveau, pas de soucis avec l'UI, ça fonctionnais bien !

  7. #7
    Membre expert
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    octobre 2008
    Messages
    1 516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : octobre 2008
    Messages : 1 516
    Points : 3 116
    Points
    3 116
    Billets dans le blog
    6

    Par défaut

    pour les fichiers module disont qu ils existent pour assurer une compatibilité avec les anciennes version de VB et qu en dotNet de nos jours il faut developper POO donc orienté objet. Alors il s agit d adopter de bonnes pratiques pour ne pas etre embêté pour des projets plus importants.

    La copie d un seul fichier je vais dire ok en une seule ligne mais pour un dossier contenant plusieurs fichiers il faudra le parcourir pour permettre une incrementation afin de mettre a jour ta pgbar.
    De plus si tu as des repertoires dans ton dossier sources contenant des fichiers alors il faudra opter pour du parcours recursif.

    En definitive c est bien dans l event dowork qu il faut y placer les calculs longs et c est dans l event progresschanged que tu mets a jour ta pgbar et le nombre de fichier copiés en utilisant e.userstate par exemple.
    enfin ne perds pas de vu que la tache du bgw se termine dans l event completed.
    Il n est pas utile d utiliser un autre thread (et ca ne se fait pas car bgw ne gere pas le thread pool !) pour compter le nombre de fichier copiés puisque tu peux obtenir le nombre en tps reel grace a e.userstate.

    dsl de ne pas livrer d exemple car je sui en deplacement sur mon mobile.

    ++

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    septembre 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : septembre 2009
    Messages : 72
    Points : 22
    Points
    22

    Par défaut Poo et récursif

    Compris pour le Poo et les modules de classe (je ne sais encore pas m'en servir mais rien de bien compliqué).

    Je reste sur mon module à l'ancienne dans l'instant, et je ferais la modif plus tard.

    En ce qui concerne la copie en mode récursif, je suis tout à fait d'accord, je pense que c'est la meilleure méthode, ça permettra de me débarrasser du thread de contrôle.

    La seule chose qu'il faudrait, c'est qu'en appelant le bgw il utilise les éléments qu'on lui donne dynamiquement, la progressbar x, le label de texte suivant qui désignera combien de fichier sur le total etc ...

    Je vais tâcher de trouver des exemples reccursif de bgw / copie en mode récursif, et je vois si j'arrive tout seul, sinon en tout cas merci déjà pour les infos très utiles !

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    septembre 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : septembre 2009
    Messages : 72
    Points : 22
    Points
    22

    Par défaut Avancement

    J'ai pas mal avancé, y'a deux ou trois bricoles sur lesquels je sèches encore, tu devrais pouvoir m'éclairer.

    J'ai pour l'instant créer un module (je sais, pas de Poo, mais j'y viendrais, je compte convertir ce module en module de class).

    Dans se module j'ai une fonction appeler " CP_CheckCopy ", qui comme son nom l'indique vérifie la faisabilité et lance la copie dans la foulée.

    elle fait appel au background worker créer pour l'occasion sans problème, et la copie se déroule bien.

    Seul truc que je ne parviens pas à comprendre comment faire, c'est comment agir sur la progressbar que cette fonction reçois en " byref ", pour en changer la valeur depuis le Worker_ProcessChanged dynamiquement sans avoir besoin de saisir le nom précis du style " form1.progressbar1.value "

    voici le code de mon module :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
     
     
    Imports System.Windows
    Imports System.ComponentModel
    Imports System.Threading
    Imports System.IO
     
    Module Module1
     
        Public Structure cp_FolderStruct
     
            Public src As String
            Public dest As String
            Public nbfile As Integer
     
        End Structure
     
        Public WithEvents CP_FolderWorker As BackgroundWorker
     
        Public Function CP_CheckCopy(ByVal src As String, ByVal dest As String, ByVal operation As Integer, Optional ByRef Pgb As ProgressBar = Nothing, Optional ByRef Total As String = "", Optional ByRef Result As String = "", Optional ByRef StartButton As Button = Nothing, Optional ByRef CancelButton As Button = Nothing)
     
     
            'operation = 0 -> copie de fichier
            'operation = 1 -> copie de dossier
     
            'retourne -1 quand retour invalide
            'retourne -2 quand opération invalide
            'retourne -3 quand pas de dossier source
     
     
            'debug
            operation = 1
     
     
            ' Reset  du label resultat.
            If IsNothing(Result) = False Then
     
                Result = ""
     
            End If
            ' Desactive start button jusqu'a fin operation 
            ' asynchrone.
     
            If IsNothing(StartButton) = False Then
                StartButton.Enabled = False
                ' Active Cancel button sur duree operation asynchrone.
            End If
     
            If IsNothing(CancelButton) = False Then
                CancelButton.Enabled = True
                ' ProgressBar1
            End If
     
            If IsNothing(Pgb) = False Then
                Pgb.Minimum = 0
                Pgb.Value = 1
            End If
            Select Case operation
                Case 0
     
                    'copie de fichiers
     
                Case 1
     
                    'copie de dossier
                    'vérication de l'existence du dossier source
                    If My.Computer.FileSystem.DirectoryExists(src) = False Then
     
                        Return -3
     
                    End If
     
     
     
                    ' Calcul Total Fichiers à copier.
                    If IsNothing(Total) = False Then
                        Total = "0"
                        Total = FilesTotal(src, CInt(Total)).ToString
                    End If
     
                    If IsNothing(Pgb) = False Then
                        Pgb.Maximum = 100
                    End If
     
                    ' Initialize BackgroudWorker.
     
                    CP_FolderWorker = New BackgroundWorker
     
                    CP_FolderWorker.WorkerReportsProgress = True
                    CP_FolderWorker.WorkerSupportsCancellation = True
     
                    Dim cpfolder As cp_FolderStruct = Nothing
     
                    cpfolder.src = src
                    cpfolder.dest = dest
                    cpfolder.nbfile = CInt(Total)
     
                    ' Demarre worker.
     
                    AddHandler CP_FolderWorker.DoWork, New DoWorkEventHandler(AddressOf cp_FolderWorker_DoWork)
                    AddHandler CP_FolderWorker.RunWorkerCompleted, New RunWorkerCompletedEventHandler(AddressOf CP_FolderWorker_RunWorkerCompleted)
                    AddHandler CP_FolderWorker.ProgressChanged, New ProgressChangedEventHandler(AddressOf CP_FolderWorker_ProgressChanged)
                    CP_FolderWorker.RunWorkerAsync(cpfolder)
     
                Case Else
     
                    Return -2
     
            End Select
     
     
     
     
     
            Return -1
     
        End Function
     
        Public Function FilesTotal(ByVal sourceDirName As String, ByVal totalFile As Integer) As Integer
            Dim dir As DirectoryInfo = New DirectoryInfo(sourceDirName)
            Dim dirs As DirectoryInfo() = dir.GetDirectories()
            Dim files As FileInfo() = dir.GetFiles()
            For Each File In files
                ' Compute total files for subdir
                totalFile = totalFile + 1
            Next File
            'appel recursif sur FilesTotal pour chaque subdir
            For Each subdir In dirs
                sourceDirName = subdir.FullName
                totalFile = FilesTotal(sourceDirName, totalFile)
            Next subdir
     
            Return totalFile
        End Function
     
        Private Sub cp_FolderWorker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles CP_FolderWorker.DoWork
     
     
            Dim cpfolder As cp_FolderStruct = e.Argument
     
            Call DirectoryCopy(cpfolder.src, cpfolder.dest, cpfolder.nbfile, CP_FolderWorker, e)
     
        End Sub
     
        Private Sub DirectoryCopy(ByVal sourceDirName As String, ByVal destDirName As String, ByVal nbfile As Integer, ByVal worker As BackgroundWorker, ByVal e As System.ComponentModel.DoWorkEventArgs)
     
            ' If the source directory does not exist, throw an exception.
            If Not Directory.Exists(sourceDirName) Then
                Throw New DirectoryNotFoundException(
                    "Source directory does not exist or could not be found: " _
                    + sourceDirName)
            End If
            ' If the destination directory does not exist, create it.
            If Not Directory.Exists(destDirName) Then
                Directory.CreateDirectory(destDirName)
            End If
            Dim dir As DirectoryInfo = New DirectoryInfo(sourceDirName)
            Dim files() As FileInfo = dir.GetFiles()
     
            For Each file As FileInfo In files
                ' Create the path to the new copy of the file.
                Dim temppath As String = Path.Combine(destDirName, file.Name)
                file.CopyTo(temppath, True)
                nbfile = nbfile + 1
                Dim percentageDone As Double = CType(nbfile / nbfile, Double) * 100.0
                worker.ReportProgress(CType(percentageDone, Integer))
            Next
            Dim dirs As DirectoryInfo() = dir.GetDirectories()
            For Each subdir As DirectoryInfo In dirs
                ' Create the subdirectory.
                Dim temppath As String =
                    Path.Combine(destDirName, subdir.Name)
                ' Copy the subdirectories.
                DirectoryCopy(subdir.FullName, temppath, nbfile, worker, e)
            Next
            e.Result = nbfile.ToString
     
        End Sub
     
        Private Sub CP_FolderWorker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles CP_FolderWorker.ProgressChanged
     
            Form1.pgb.Value = e.ProgressPercentage
     
        End Sub
     
        Private Sub CP_FolderWorker_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles CP_FolderWorker.RunWorkerCompleted
            ' handle  an exception was thrown.
            If (e.Error IsNot Nothing) Then
                MessageBox.Show(e.Error.Message)
            ElseIf e.Cancelled Then
     
                'result doit avoir pour valleur " annulation " + annulation de l'ajout dans la base de donnée
     
     
            Else
                'succès
     
                'result = e.Result.ToString()
            End If
            ' Active Start button.
            ' StartButton.Enabled = True
     
            ' Desactive Cancel button.
            ' CancelButton.Enabled = False
     
     
        End Sub
     
    End Module

    C'est encore assez " brut de décoffrage ", mais j'ai fais ça en 20 minutes ce matin depuis une source trouvée ici :

    https://www.developpez.net/forums/d1...e-progression/

    J'ai juste tout repris de la form, adapté à mes besoins et bouger ça dans un module à l'arrache.

    Je précise que j'ai tester la source en question qui fonctionne bien au départ, elle est juste prévue pour être utiliser directement dans la form avec les éléments contenu à l'intérieur, pas avec des éléments externe à un module chargée dynamiquement avec la fonction.

  10. #10
    Membre expert
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    octobre 2008
    Messages
    1 516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : octobre 2008
    Messages : 1 516
    Points : 3 116
    Points
    3 116
    Billets dans le blog
    6

    Par défaut

    Regardes par ici :



    Même si j'avoue que ce ne soit pas la meilleure solution.

    ++

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    septembre 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : septembre 2009
    Messages : 72
    Points : 22
    Points
    22

    Par défaut réponse

    Je ne vois rien dans ta réponse, c'est normal ?

  12. #12
    Membre expert
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    octobre 2008
    Messages
    1 516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : octobre 2008
    Messages : 1 516
    Points : 3 116
    Points
    3 116
    Billets dans le blog
    6

    Par défaut

    ---> Une classe Form1

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
     
    Imports System.ComponentModel
    Imports System.IO
     
    Public Class Form1
        Inherits Form
     
        Private WithEvents m_CopyWorker As BackgroundWorker
        Private WithEvents m_TxbSource As TextBox
        Private WithEvents m_TxbDestination As TextBox
        Private WithEvents m_LblSource As Label
        Private WithEvents m_LblDestination As Label
        Private WithEvents m_BtnStartCancel As Button
        Private WithEvents m_PgbCopyProgress As ProgressBar
        Private WithEvents m_LblState As Label
        Private WithEvents m_LblCopyState As Label
     
        Public Sub New()
            ' instanciation du Bgw
            m_CopyWorker = New BackgroundWorker With {.WorkerSupportsCancellation = True, .WorkerReportsProgress = True}
            ' instanciation et initialisation des contrôles
            m_TxbSource = New TextBox With {.Name = "TxbSource", .Size = New Size(362, 20), .Location = New Point(106, 24)}
            m_TxbDestination = New TextBox With {.Name = "TxbDestination", .Size = New Size(362, 20), .Location = New Point(106, 50)}
            m_LblSource = New Label With {.Name = "LblSource", .AutoSize = True, .Text = "Source :", .Size = New Size(47, 13), .Location = New Point(31, 27)}
            m_LblDestination = New Label With {.Name = "LblDestination", .AutoSize = True, .Text = "Destination :", .Size = New Size(66, 13), .Location = New Point(12, 53)}
            m_BtnStartCancel = New Button With {.Name = "BtnStartCancel", .Text = "Lancer la copie", .Size = New Size(362, 23), .Location = New Point(106, 93)}
            m_PgbCopyProgress = New ProgressBar With {.Name = "PgbCopyProgress", .Size = New Size(362, 23), .Location = New Point(106, 159)}
            m_LblState = New Label With {.Name = "LblState", .AutoSize = True, .Text = "Etat :", .Size = New Size(32, 13), .Location = New Point(46, 133)}
            m_LblCopyState = New Label With {.Name = "LblCopyState", .AutoSize = False, .Text = "", .Size = New Size(365, 23), .Location = New Point(103, 133)}
            ' Initialisation du Container de type Form1 et ajout des contrôles
            Me.Name = "Form1"
            Me.Text = "Form1"
            Me.AutoScaleDimensions = New SizeF(6.0!, 13.0!)
            Me.AutoScaleMode = AutoScaleMode.Font
            Me.ClientSize = New Size(521, 196)
            Me.Controls.Add(m_LblCopyState)
            Me.Controls.Add(m_LblState)
            Me.Controls.Add(m_PgbCopyProgress)
            Me.Controls.Add(m_BtnStartCancel)
            Me.Controls.Add(m_LblDestination)
            Me.Controls.Add(m_LblSource)
            Me.Controls.Add(m_TxbDestination)
            Me.Controls.Add(m_TxbSource)
        End Sub
     
        Private Sub m_BtnStartCancel_Click(sender As Object, e As EventArgs) Handles m_BtnStartCancel.Click
            If m_BtnStartCancel.Text = "Lancer la copie" Then
                If Directory.Exists(m_TxbSource.Text) = False OrElse Directory.Exists(m_TxbDestination.Text) = False Then
                    MsgBox("Veuillez saisir un chemin valide !")
                Else
                    If Not m_CopyWorker.IsBusy Then
                        m_BtnStartCancel.Text = "Annuler la copie"
                        m_CopyWorker.RunWorkerAsync(Tuple.Create(m_TxbSource.Text, m_TxbDestination.Text))
                    End If
                End If
            ElseIf m_BtnStartCancel.Text = "Annuler la copie" Then
                m_CopyWorker.CancelAsync()
            End If
        End Sub
     
        Private Sub m_CopyWorker_RunWorkerAsync(sender As Object, e As DoWorkEventArgs) Handles m_CopyWorker.DoWork
            Dim Tuples As Tuple(Of String, String) = TryCast(e.Argument, Tuple(Of String, String))
     
            Dim dir As DirectoryInfo = New DirectoryInfo(Tuples.Item1)
            ' On retourne le nombre de fichiers total dans le chemin source y compris ceux des sous répertoires
            Dim allFiles() As FileInfo = dir.GetFiles("*", SearchOption.AllDirectories)
            Dim FilesCount% = allFiles.Count
            ' On déclare et initie une variable local qui sera passsée par référence à la méthode DirectoryCopy de manière à incrémenter correctement dans la récursivité
            Dim LocalFilesCount% = 0
     
            Copy.DirectoryCopy(Tuples.Item1, Tuples.Item2, FilesCount, LocalFilesCount, m_CopyWorker, e)
        End Sub
     
        Private Sub m_CopyWorker_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles m_CopyWorker.ProgressChanged
            ' On mets à jour l'UI
            m_PgbCopyProgress.Value = e.ProgressPercentage
            m_LblCopyState.Text = e.UserState.ToString
        End Sub
     
        Private Sub m_CopyWorker_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles m_CopyWorker.RunWorkerCompleted
            ' On gère ce qui a été déclenché à l'issue ou lors de la copie
            If e.Cancelled Then
                MsgBox("Copie annulée")
            ElseIf e.Error IsNot Nothing Then
                MsgBox("erreur lors de la copie")
            Else
                MsgBox(e.Result(0) & vbNewLine & e.Result(1))
            End If
            ' On réinitialise les contrôles
            m_PgbCopyProgress.Value = 0
            m_LblCopyState.Text = String.Empty
            m_BtnStartCancel.Text = "Lancer la copie"
        End Sub
     
     
    End Class

    --> Une classe Copy

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    Imports System.ComponentModel
    Imports System.IO
     
    Public Class Copy
     
        Public Shared Sub DirectoryCopy(sourceDirName As String, destDirName As String, ByRef nbFiles As Integer, ByRef nbLocalFiles As Integer, Bgw As BackgroundWorker, ByVal e As DoWorkEventArgs)
            Try
                Dim dir As DirectoryInfo = New DirectoryInfo(sourceDirName)
                Dim files() As FileInfo = dir.GetFiles()
     
                For Each file As FileInfo In files
                    If Bgw.CancellationPending Then
                        e.Cancel = True
                        Exit Sub
                    End If
                    ' Create the path to the new copy of the file.
                    Dim temppath As String = Path.Combine(destDirName, file.Name)
                    file.CopyTo(temppath, True)
                    nbLocalFiles += 1
                    Bgw.ReportProgress((nbLocalFiles / nbFiles) * 100, "Traitement de : " & file.FullName)
                Next
                Dim dirs As DirectoryInfo() = dir.GetDirectories()
                For Each subdir As DirectoryInfo In dirs
                    If Bgw.CancellationPending Then
                        e.Cancel = True
                        Exit Sub
                    End If
                    ' Create the subdirectory.
                    Dim temppath As String = Path.Combine(destDirName, subdir.Name)
                    If Not Directory.Exists(temppath) Then
                        Directory.CreateDirectory(temppath)
                    End If
                    ' Copy the subdirectories.
                    DirectoryCopy(subdir.FullName, temppath, nbFiles, nbLocalFiles, Bgw, e)
                Next
            Catch ex As Exception
                e.Result = New String() {"Erreur", ex.ToString}
            End Try
     
            e.Result = New String() {"Achevée", "Opération réussie"}
     
        End Sub
     
    End Class

    Attention pour la copie de fichiers volumineux il vaut mieux incrémenter per/Bytes et non per/file.

    PS : C est le principe, il y a certainement des choses à revoir....

    Cdlt

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    septembre 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : septembre 2009
    Messages : 72
    Points : 22
    Points
    22

    Par défaut Vidéo + class

    - Je n'ai pas encore vu ta vidéo, je ne sais pas pourquoi de Belgique elle n'était pas visible (j'étais en week end depuis vendredi)

    - concernant la class copy, mon seul problème c'est de ne pas savoir l'utiliser, rien à voir avec du C / C++ que j'utilise en général avec de simple fonction et entête.

    On m'a simplement foutu ce projet VB.net dans les pattes alors que j'ai vu ça en cours y'a longtemps (on parlait à l'époque de VB6 et Win XP), je me rends bien compte qu'on est bien loin de tout ça.

    Le soucis principal dans la vidéo que tu m'a donné est le fait qu'il utilise des contrôles connu à chaque fois, qui ne sont pas dynamique.

    Si un collègue veut réutiliser ma source, il devra importer dans son projet le module / module de class de copie, utiliser une fonction seule à qui il passe en paramètre ces contrôles, l'objectif c'est ça.

    Sinon j'ai plein de source qui font le boulot en file per file qui fonctionne mais chaque fois avec une form définie et des contrôle connu jamais dynamique ...

    Avant de passer en bytes per bytes, pourrait-on réutiliser mon module afin déjà d'y rendre dynamique les contrôle ? je reprendrais le bytes per bytes de la vidéo plus tard pour en faire le changement, ça me parait pas mal.

    On pourrait passer par ta source mais il faudrait que tout soit dispo dans le module de class directement ça ne me pose pas de soucis.

    De ce que j'ai vu par contre, pour raison de " compatibilité ", tous les 2 dev qui restent ou je bosse utilise des modules, pas des modules de class, en cause de vieux projet développé y'a Mathusalem ...

    Tant que je sais me servir du module de class comme c'est une " nouvelle source " ça peut avoir un module de class ce n'est pas un soucis.

    En tout cas merci wallace1 de m'aider dans tout ça, moi le VB ça me sort pas les trous de nez ^^.

  14. #14
    Membre expert
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    octobre 2008
    Messages
    1 516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : octobre 2008
    Messages : 1 516
    Points : 3 116
    Points
    3 116
    Billets dans le blog
    6

    Par défaut

    Bonjour,

    Donc pour résumer, en somme :

    - Tu veux une classe de gestion de copie mais tu ne sais pas comment fonctionne une classe en DotNet ???
    - La source que je te propose plus haut (pas la vidéo mais la classe Form1 et Copy) possède des contrôles créés dynamiquement donc tu peux très bien l'adapter pour en faire une classe qui sera greffée dans un projet VS. Maintenant si tu souhaites en faire une classe de gestion il faudra mettre en place des événements et délégués afin que ce soit récupérable dans le corps du projet principal.

    Je comprends rien à la totalité de ton intervention précédente........

  15. #15
    Membre à l'essai
    Profil pro
    Inscrit en
    septembre 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : septembre 2009
    Messages : 72
    Points : 22
    Points
    22

    Par défaut classe dot.net

    Et non, j'ai appris à une époque ou le " poo " n'était pas la priorité de mon prof de l'époque. Pour dire, on bossais sous VB6 alors qu'était déjà sorti Framework 3.5, s'était un choix volontaire de l’aveu de notre prof de l'époque.

    Du coup, on bossait avec des modules uniquement et point, avec des fonctions.

    Pour finir je n'ai pas bosser en VB depuis ma sortie de l'école, je remplace quelqu'un sur ce projet, sinon je dev principalement en langage C type application console linux, ça n'a strictement rien à voir.

    Je suis pris sur un projet C parallèlement à ce projet en VB, ce projet n'étant pas urgent étant donné les délais, je peux me permettre de temporisé c'est pourquoi je ne prends pas trop le temps de voir ...

    Du fait, un lien pour comprendre facilement l'utilisation d'une classe ?

    Citation Envoyé par wallace1 Voir le message
    Bonjour,

    Donc pour résumer, en somme :

    - Tu veux une classe de gestion de copie mais tu ne sais pas comment fonctionne une classe en DotNet ???
    - La source que je te propose plus haut (pas la vidéo mais la classe Form1 et Copy) possède des contrôles créés dynamiquement donc tu peux très bien l'adapter pour en faire une classe qui sera greffée dans un projet VS. Maintenant si tu souhaites en faire une classe de gestion il faudra mettre en place des événements et délégués afin que ce soit récupérable dans le corps du projet principal.

    Je comprends rien à la totalité de ton intervention précédente........

  16. #16
    Membre expert
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    octobre 2008
    Messages
    1 516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : octobre 2008
    Messages : 1 516
    Points : 3 116
    Points
    3 116
    Billets dans le blog
    6

    Par défaut

    tu disais plus haut que tu developpais en C++ ...... n est ce pas un langage objet......... breffff.....

    tu trouveras ce qu il te faut dans le cours de p. lasserre :

    http://plasserre.developpez.com/cours/vb-net/

    @+

  17. #17
    Membre à l'essai
    Profil pro
    Inscrit en
    septembre 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : septembre 2009
    Messages : 72
    Points : 22
    Points
    22

    Par défaut

    Tu as tout à fait raison sur ce point,

    J'ai été formé en apprentissage sur le C pour une question de langage plus bas niveau.

    Ceux qui font du C++ (que je dépanne de temps à autre), font plus du GUI avec QT par exemple.

    Mais j'avoue que je me lance seulement dans la POO ... et vraiment.

    Je ne t'embête plus, je prends les modules de classes depuis le début et je vais me débrouiller, je me débrouille impec avec les backgroundworker maintenant, j'ai les fonctions qui conviennent même en bytes per bytes récursivement parlant que je n'ai qu'à adapté, je suis bon pour la suite.

    Un grand merci en tout cas d'avoir eu à me supporté, je suis pas toujours facile ni explicite ...

    Bref, merci

    Citation Envoyé par wallace1 Voir le message
    tu disais plus haut que tu developpais en C++ ...... n est ce pas un langage objet......... breffff.....

    tu trouveras ce qu il te faut dans le cours de p. lasserre :

    http://plasserre.developpez.com/cours/vb-net/

    @+

  18. #18
    Membre à l'essai
    Profil pro
    Inscrit en
    septembre 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : septembre 2009
    Messages : 72
    Points : 22
    Points
    22

    Par défaut Merci

    J'ai finalement tout converti dans mon projet en module de class, c'est clairement " plus simple " et plus pratique d'appeler des méthodes " .faitsi " ...

    Merci d'avoir perdu beaucoup de temps à me convaincre que depuis le début j'étais dans l'erreur,

    la prochaine fois j'arrêterais de m'entêter.

Discussions similaires

  1. [Batch] Copie Certains Dossiers (avec leurs arborescences)
    Par stzurg dans le forum Scripts/Batch
    Réponses: 1
    Dernier message: 28/08/2011, 14h19
  2. Javascript copy de repertoire avec barre de progression
    Par avalokitech dans le forum JavaScript
    Réponses: 5
    Dernier message: 10/01/2011, 16h56
  3. copie de répertoire avec barre de progression
    Par s7even dans le forum Windows Forms
    Réponses: 5
    Dernier message: 10/12/2009, 19h36
  4. Copie de fichier avec barre de progression
    Par Papy214 dans le forum C#
    Réponses: 6
    Dernier message: 06/11/2008, 10h17
  5. Copie de fichiers avec détails de progression
    Par Shypster dans le forum C#
    Réponses: 1
    Dernier message: 04/11/2008, 22h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo