Application client/serveur (mise à jour MD5)

Fermé
cs_lebuff Messages postés 39 Date d'inscription lundi 15 août 2011 Statut Membre Dernière intervention 17 juillet 2013 - 15 août 2011 à 12:09
cs_lebuff Messages postés 39 Date d'inscription lundi 15 août 2011 Statut Membre Dernière intervention 17 juillet 2013 - 24 août 2011 à 12:37
Bonjour à tous, je suis un gros débutant sur visual studio, j'aurai aimé avoir quelques informations.

Tout d'abord je souhaite créer une application qui permette en plus de ses fonctionnalités (boutons de lancement d'applications par exemple) de servir d'auto updater. Je vous explique, le principe serait qu'à chaque lancement de l'application, elle fasse les mises à jours disponibles automatiquement si la partie client n'est pas à jour.
J'ai donc pensé à un principe:

1)L'application va voir à une adresse (ex: [url]http://www.monsite.fr/updater/liste.txt/url )

2)Nous avons donc un fichier liste.txt hébergé sur un serveur, celui ci contient la liste de tous les derniers fichiers en date suivi de leur empreinte MD5.

exemple de liste.txt:
fichier1.txt 2734d8940268ac0d5a3d3be90dc895f8
fichier2.exe a4b64724173983950a615a2f20ffc054
fichier3.rar 111c49991c07f94fe30de049b6342623
/dossier1/fichier4.exe 1dffff0bf0f0c4ba4a72fbc357e53574
/dossier2/fichier5.exe 812bd3810c0f12592ad197a33964d159


3)Les fichiers correspondants sont hébergés sur le même serveur dans un dossier qui contient tous les fichiers du liste.txt, tous les fichiers du dernier client à jour alors. (exemple: [url]http://www.monsite.fr/updater/application//url)

4)L'application compare les empreintes MD5 des fichiers du client avec ceux du fichier liste.txt hébergé sur le site. Si les fichiers n'existent pas ou si l'empreinte MD5 n'est pas la même, l'application télécharge le ou les fichiers qu'il faut (ceux qui sont hébergés sur le site: [url]http://www.monsite.fr/updater/application//url )

5)Si toutes les empreintes MD5 correspondent ou lorsque l'application a fini de télécharger les derniers fichiers les boutons se dévérouillent.

Ce projet est-il possible à votre avis ? Cela fonctionnerait-il ? Existe-il une autre méthode plus pertinente que la "méthode MD5" pour permettre de différencier deux fichiers sachant qu'ils auraient le même nom et quasimment si ce n'est exactement la même taille ? Et est-ce que des personnes pourraient m'aider à la réalisation de cette partie de mon application.

J'ai trouvé quelques bouts de codes:
[url]http://www.vbfrance.com/codes/CHECKSUM-SHA1-MD5-FICHIER_43669.aspx/url
[url]http://www.vbfrance.com/codes/MD5-CHECK-SUM_33257.aspx/url
[url]http://www.vbfrance.com/codes/VERIFIER-NOUVELLE-VERSION-APPLICATION-VB-PARTIR-INTERNET_39179.aspx/url

Je pense qu'ils pourraient grandement aider à la réalisation de l'application, si des gens expérimentés pouvaient me venir en aide et m'aider à réaliser cette partie de mon application je serais vraiment soulagé.

Cordialement.

28 réponses

cs_lebuff Messages postés 39 Date d'inscription lundi 15 août 2011 Statut Membre Dernière intervention 17 juillet 2013
18 août 2011 à 20:22
J'ai finalement réussi à faire fonctionner la première partie du code comme ceci :
Option Strict On
Imports System.IO
Imports System.Net
Imports System.Threading

Public Class pctDownload
    Inherits PictureBox
    Dim b As Bitmap
    Dim g As Graphics
    Dim ft As New Font("Arial", 12, FontStyle.Regular, GraphicsUnit.Pixel)
    Dim f As IO.FileStream
    Dim m_Fichier, m_Destination As String
    Event Complet(ByVal Fichier As String)
    Delegate Sub Progress(ByVal Cours As Integer, ByVal Total As Integer)

    Public Sub New(ByVal Fichier As String, ByVal Destination As String, ByVal Largeur As Integer, ByVal Hauteur As Integer)
        With Me
            .Width = Largeur
            .Height = Hauteur
            .BorderStyle = Windows.Forms.BorderStyle.FixedSingle
        End With
        b = New Bitmap(Largeur, Hauteur)
        g = Graphics.FromImage(b)
        m_Fichier = Fichier
        m_Destination = Destination
        g.FillRectangle(Brushes.LightSteelBlue, b.GetBounds(GraphicsUnit.Pixel))
        g.DrawString("0.00 %", ft, Brushes.White, Convert.ToInt32(Largeur / 2) - 15, 2)
        Me.Image = CType(b.Clone, Image)
    End Sub

    Public Sub Start()
        Dim t As New Thread(AddressOf Telecharge)
        t.Start()
    End Sub

    Private Sub Telecharge()
        Dim fic As String = m_Fichier.Substring(m_Fichier.LastIndexOf("/") + 1)
        Dim webr As WebRequest = HttpWebRequest.Create(m_Fichier)
        Dim webrequest As HttpWebRequest = DirectCast(webr, HttpWebRequest)
        Dim Length As Integer
        Dim rcvStream As Stream

        webrequest.Method = "GET"
        webrequest.Pipelined = False
        webrequest.KeepAlive = False
        webrequest.Credentials = New System.Net.CredentialCache
        webrequest.AuthenticationLevel = Security.AuthenticationLevel.MutualAuthRequested
        webrequest.Timeout = 9000
        webrequest.ProtocolVersion = New Version(1, 1)
        webrequest.ContentType = "*/*"
        webrequest.AllowAutoRedirect = True
        webrequest.MaximumAutomaticRedirections = 10

        Dim webrep As WebResponse = webrequest.GetResponse
        Dim webreponse As HttpWebResponse = DirectCast(webrep, HttpWebResponse)

        Length = Convert.ToInt32(webreponse.ContentLength)
        rcvStream = webreponse.GetResponseStream
        Dim buf(1024) As Byte
        Dim bytesread As Integer
        Dim fw As BinaryWriter = Nothing
        Try
            f = New FileStream(m_Destination & fic, FileMode.CreateNew)
            fw = New BinaryWriter(f)
        Catch
            Do
                Dim rd As New Random
                fic = rd.Next(0, 2000000).ToString & "_" & fic
                If My.Computer.FileSystem.FileExists(m_Destination & fic) = False Then Exit Do
            Loop
            f = New FileStream(m_Destination & fic, FileMode.OpenOrCreate)
            fw = New BinaryWriter(f)
        End Try
        Do
            bytesread = rcvStream.Read(buf, 0, buf.Length)
            fw.Write(buf, 0, bytesread)
            If Me.InvokeRequired Then Me.Invoke(New Progress(AddressOf Progression), Convert.ToInt32(f.Length), Length)
        Loop Until bytesread = 0

        fw.Close()
        f.Close()
    End Sub

    Private Sub Progression(ByVal Cours As Integer, ByVal Total As Integer)
        g.FillRectangle(Brushes.LightSteelBlue, b.GetBounds(GraphicsUnit.Pixel))
        Dim c As New Rectangle(0, 0, Convert.ToInt32((Cours / Total) * b.Width), b.Height)
        g.FillRectangle(Brushes.SteelBlue, c)
        Dim lft As SizeF = g.MeasureString(String.Format("{0:0.00%}", Cours / Total), ft, SizeF.Empty, StringFormat.GenericDefault)
        g.DrawString(String.Format("{0:0.00%}", Cours / Total), ft, Brushes.White, Convert.ToInt32((b.Width / 2) - (lft.Width / 2)), 2)
        Me.Image = CType(b.Clone, Image)
        If Cours = Total Then
            RaiseEvent Complet(m_Fichier)
        End If
    End Sub
    Friend WithEvents Button1 As System.Windows.Forms.Button
    Friend WithEvents ProgressBar1 As System.Windows.Forms.ProgressBar

    Private Sub InitializeComponent()
        Me.Button1 = New System.Windows.Forms.Button()
        Me.ProgressBar1 = New System.Windows.Forms.ProgressBar()
        CType(Me, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(0, 0)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(75, 23)
        Me.Button1.TabIndex = 0
        Me.Button1.Text = "Button1"
        Me.Button1.UseVisualStyleBackColor = True
        '
        'ProgressBar1
        '
        Me.ProgressBar1.Location = New System.Drawing.Point(0, 0)
        Me.ProgressBar1.Name = "ProgressBar1"
        Me.ProgressBar1.Size = New System.Drawing.Size(100, 23)
        Me.ProgressBar1.TabIndex = 0
        CType(Me, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)

    End Sub
End Class

Public Class Form1
    'déclaration du picturebox avec son événement
    Dim WithEvents ProgressB As pctDownload
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'si les fichiers listelocale.txt et liste.txt existent, on les suppriment
        If My.Computer.FileSystem.FileExists(Application.StartupPath & "\listelocale.txt") Then
            My.Computer.FileSystem.DeleteFile(Application.StartupPath & "\listelocale.txt")
        End If
        If My.Computer.FileSystem.FileExists(Application.StartupPath & "\liste.txt") Then
            My.Computer.FileSystem.DeleteFile(Application.StartupPath & "\liste.txt")
        End If

        Dim repertoire() As IO.FileInfo = New IO.DirectoryInfo(Application.StartupPath).GetFiles("*", IO.SearchOption.AllDirectories)
        'écriture de la liste locale des fichiers 
        Using writer As New IO.StreamWriter(Application.StartupPath & "\listelocale.txt", False, System.Text.Encoding.Default)
            For Each fichier As IO.FileInfo In repertoire
                'avec leur nom et leur MD5 séparé par un espace 
                'Note: le choix de l'espace pour la séparation n'est peut-être pas judicieux
                'utiliser New Char() {Convert.ToChar(1)}  pour un meilleur séparateur
                'utilise fichier.FullName pour écrire le chemin complet du fichier
                Dim fichier_p As String = fichier.FullName.Replace(Application.StartupPath, "").Substring(1)
                writer.WriteLine(fichier_p & " " & MD5File(fichier.FullName))
            Next
        End Using
        'instanciation de la classe
        ProgressB = New pctDownload("http://monsite.fr/updater/liste.txt", Application.StartupPath & "", 200, 22)

        'ajout de la picturebox au formulaire
        Me.Controls.Add(ProgressB)
        'démarrage du téléchargement
        ProgressB.Start()
    End Sub
    'si les fichiers listelocale.txt et liste.txt existent, on les suppriment
    'fonction de hashage MD5
    Private Function MD5File(ByVal nFichier As String) As String
        Dim md5 As New System.Security.Cryptography.MD5CryptoServiceProvider
        Dim fmd5 As New IO.FileStream(nFichier, IO.FileMode.Open, IO.FileAccess.Read)
        md5.ComputeHash(fmd5)
        Dim hash As Byte() = md5.Hash
        Dim buff As System.Text.StringBuilder = New System.Text.StringBuilder
        Dim hashByte As Byte
        For Each hashByte In hash
            buff.Append(String.Format("{0:X2}", hashByte))
        Next
        md5.Clear()
        fmd5.Close()
        fmd5.Dispose()
        Return buff.ToString
    End Function
End Class


Je vois bien l'application (interface) dès son lancement et tout fonctionne (le début), c'est à dire les fichiers sont supprimés, le fichier listelocale.txt est créé, le fichier liste.txt est téléchargé et la barre de chargement se remplit. Mais cela ne marche qu'une fois sur deux, j'ai souvent une erreur l'application a cessé de fonctionner... Même quand ça ne bug pas on attend un peu avant que le téléchargement ne se lance. La ligne " Dim webrep As WebResponse = webrequest.GetResponse" est souvent citée. Et lorsque j'essaye de compléter le code de cette façon :
Option Strict On
Imports System.IO
Imports System.Net
Imports System.Threading

Public Class pctDownload
    Inherits PictureBox
    Dim b As Bitmap
    Dim g As Graphics
    Dim ft As New Font("Arial", 12, FontStyle.Regular, GraphicsUnit.Pixel)
    Dim f As IO.FileStream
    Dim m_Fichier, m_Destination As String
    Event Complet(ByVal Fichier As String)
    Delegate Sub Progress(ByVal Cours As Integer, ByVal Total As Integer)

    Public Sub New(ByVal Fichier As String, ByVal Destination As String, ByVal Largeur As Integer, ByVal Hauteur As Integer)
        With Me
            .Width = Largeur
            .Height = Hauteur
            .BorderStyle = Windows.Forms.BorderStyle.FixedSingle
        End With
        b = New Bitmap(Largeur, Hauteur)
        g = Graphics.FromImage(b)
        m_Fichier = Fichier
        m_Destination = Destination
        g.FillRectangle(Brushes.LightSteelBlue, b.GetBounds(GraphicsUnit.Pixel))
        g.DrawString("0.00 %", ft, Brushes.White, Convert.ToInt32(Largeur / 2) - 15, 2)
        Me.Image = CType(b.Clone, Image)
    End Sub

    Public Sub Start()
        Dim t As New Thread(AddressOf Telecharge)
        t.Start()
    End Sub

    Private Sub Telecharge()
        Dim fic As String = m_Fichier.Substring(m_Fichier.LastIndexOf("/") + 1)
        Dim webr As WebRequest = HttpWebRequest.Create(m_Fichier)
        Dim webrequest As HttpWebRequest = DirectCast(webr, HttpWebRequest)
        Dim Length As Integer
        Dim rcvStream As Stream

        webrequest.Method = "GET"
        webrequest.Pipelined = False
        webrequest.KeepAlive = False
        webrequest.Credentials = New System.Net.CredentialCache
        webrequest.AuthenticationLevel = Security.AuthenticationLevel.MutualAuthRequested
        webrequest.Timeout = 9000
        webrequest.ProtocolVersion = New Version(1, 1)
        webrequest.ContentType = "*/*"
        webrequest.AllowAutoRedirect = True
        webrequest.MaximumAutomaticRedirections = 10

        Dim webrep As WebResponse = webrequest.GetResponse
        Dim webreponse As HttpWebResponse = DirectCast(webrep, HttpWebResponse)

        Length = Convert.ToInt32(webreponse.ContentLength)
        rcvStream = webreponse.GetResponseStream
        Dim buf(1024) As Byte
        Dim bytesread As Integer
        Dim fw As BinaryWriter = Nothing
        Try
            f = New FileStream(m_Destination & fic, FileMode.CreateNew)
            fw = New BinaryWriter(f)
        Catch
            Do
                Dim rd As New Random
                fic = rd.Next(0, 2000000).ToString & "_" & fic
                If My.Computer.FileSystem.FileExists(m_Destination & fic) = False Then Exit Do
            Loop
            f = New FileStream(m_Destination & fic, FileMode.OpenOrCreate)
            fw = New BinaryWriter(f)
        End Try
        Do
            bytesread = rcvStream.Read(buf, 0, buf.Length)
            fw.Write(buf, 0, bytesread)
            If Me.InvokeRequired Then Me.Invoke(New Progress(AddressOf Progression), Convert.ToInt32(f.Length), Length)
        Loop Until bytesread = 0

        fw.Close()
        f.Close()
    End Sub

    Private Sub Progression(ByVal Cours As Integer, ByVal Total As Integer)
        g.FillRectangle(Brushes.LightSteelBlue, b.GetBounds(GraphicsUnit.Pixel))
        Dim c As New Rectangle(0, 0, Convert.ToInt32((Cours / Total) * b.Width), b.Height)
        g.FillRectangle(Brushes.SteelBlue, c)
        Dim lft As SizeF = g.MeasureString(String.Format("{0:0.00%}", Cours / Total), ft, SizeF.Empty, StringFormat.GenericDefault)
        g.DrawString(String.Format("{0:0.00%}", Cours / Total), ft, Brushes.White, Convert.ToInt32((b.Width / 2) - (lft.Width / 2)), 2)
        Me.Image = CType(b.Clone, Image)
        If Cours = Total Then
            RaiseEvent Complet(m_Fichier)
        End If
    End Sub
    Friend WithEvents Button1 As System.Windows.Forms.Button
    Friend WithEvents ProgressBar1 As System.Windows.Forms.ProgressBar

    Private Sub InitializeComponent()
        Me.Button1 = New System.Windows.Forms.Button()
        Me.ProgressBar1 = New System.Windows.Forms.ProgressBar()
        CType(Me, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(0, 0)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(75, 23)
        Me.Button1.TabIndex = 0
        Me.Button1.Text = "Button1"
        Me.Button1.UseVisualStyleBackColor = True
        '
        'ProgressBar1
        '
        Me.ProgressBar1.Location = New System.Drawing.Point(0, 0)
        Me.ProgressBar1.Name = "ProgressBar1"
        Me.ProgressBar1.Size = New System.Drawing.Size(100, 23)
        Me.ProgressBar1.TabIndex = 0
        CType(Me, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)

    End Sub
End Class

Public Class Form1
    'déclaration du picturebox avec son événement
    Dim WithEvents ProgressB As pctDownload
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'si les fichiers listelocale.txt et liste.txt existent, on les suppriment
        If My.Computer.FileSystem.FileExists(Application.StartupPath & "\listelocale.txt") Then
            My.Computer.FileSystem.DeleteFile(Application.StartupPath & "\listelocale.txt")
        End If
        If My.Computer.FileSystem.FileExists(Application.StartupPath & "\liste.txt") Then
            My.Computer.FileSystem.DeleteFile(Application.StartupPath & "\liste.txt")
        End If

        Dim repertoire() As IO.FileInfo = New IO.DirectoryInfo(Application.StartupPath).GetFiles("*", IO.SearchOption.AllDirectories)
        'écriture de la liste locale des fichiers 
        Using writer As New IO.StreamWriter(Application.StartupPath & "\listelocale.txt", False, System.Text.Encoding.Default)
            For Each fichier As IO.FileInfo In repertoire
                'avec leur nom et leur MD5 séparé par un espace 
                'Note: le choix de l'espace pour la séparation n'est peut-être pas judicieux
                'utiliser New Char() {Convert.ToChar(1)}  pour un meilleur séparateur
                'utilise fichier.FullName pour écrire le chemin complet du fichier
                Dim fichier_p As String = fichier.FullName.Replace(Application.StartupPath, "").Substring(1)
                writer.WriteLine(fichier_p & " " & MD5File(fichier.FullName))
            Next
        End Using
        'instanciation de la classe
        ProgressB = New pctDownload("http://www.taurusmt2.fr/updater/liste.txt", Application.StartupPath & "", 200, 22)

        'ajout de la picturebox au formulaire
        Me.Controls.Add(ProgressB)
        'démarrage du téléchargement
        ProgressB.Start()
        'comparaison...
        Using reader_dist As New IO.StreamReader(Application.StartupPath & "\liste.txt")
            Do While Not reader_dist.EndOfStream
                'lecture de la ligne du fichier
                Dim ligne_dist As String = reader_dist.ReadLine
                'séparation des informations
                Dim fichier_dist As String = ligne_dist.Split(" "c)(0)
                Dim md5_dist As String = ligne_dist.Split(" "c)(1)
                Dim fichier_loc As String = ""
                Using reader_loc As New IO.StreamReader(Application.StartupPath & "\listelocale.txt")
                    Dim fichierexiste As Boolean = False
                    Do While Not reader_loc.EndOfStream
                        Dim ligne_loc As String = reader_loc.ReadLine
                        fichier_loc = ligne_loc.Split(" "c)(0)
                        Dim md5_loc As String = ligne_loc.Split(" "c)(1)
                        'fichiers de même nom
                        If fichier_dist = fichier_loc Then
                            'le md5 est différent
                            If md5_dist <> md5_loc Then
                                Debug.Print("md5 différent : téléchargement de " & fichier_dist)
                                'instanciation de la classe
                                ProgressB = New pctDownload("http://monsite.fr/updater/pack/" & fichier_dist, Application.StartupPath & "" & fichier_dist, 200, 22)


                                'ajout de la picturebox au formulaire
                                Me.Controls.Add(ProgressB)
                                'démarrage du téléchargement
                                ProgressB.Start()
                            Else
                                'le hash est le même (on peut effectuer une action ici)
                                Debug.Print("fichier existe (md5 égal) " & fichier_dist)
                            End If
                            fichierexiste = True
                            Exit Do
                        End If
                    Loop
                    'si le fichier n'existe pas on le télécharge
                    If Not fichierexiste Then
                        Debug.Print("fichier introuvable : telechargement de " & fichier_dist)
                        'instanciation de la classe
                        ProgressB = New pctDownload("http://monsite.fr/updater/pack/" & fichier_dist, Application.StartupPath & "" & fichier_dist, 200, 22)


                        'ajout de la picturebox au formulaire
                        Me.Controls.Add(ProgressB)
                        'démarrage du téléchargement
                        ProgressB.Start()
                    End If
                End Using
            Loop
        End Using
    End Sub
    'si les fichiers listelocale.txt et liste.txt existent, on les suppriment
    'fonction de hashage MD5
    Private Function MD5File(ByVal nFichier As String) As String
        Dim md5 As New System.Security.Cryptography.MD5CryptoServiceProvider
        Dim fmd5 As New IO.FileStream(nFichier, IO.FileMode.Open, IO.FileAccess.Read)
        md5.ComputeHash(fmd5)
        Dim hash As Byte() = md5.Hash
        Dim buff As System.Text.StringBuilder = New System.Text.StringBuilder
        Dim hashByte As Byte
        For Each hashByte In hash
            buff.Append(String.Format("{0:X2}", hashByte))
        Next
        md5.Clear()
        fmd5.Close()
        fmd5.Dispose()
        Return buff.ToString
    End Function
End Class


L'interface ne se lance pas et j'obtiens une erreur Microsoft.NET Framework Could not find file "C:\Users\...\Debug\liste.txt
Il doit y avoir une autre fonction qui comme DownLoadFile empêche l'exécution du code.
Et j'aimerais savoir comment modifier la partie interface avec le début de code je ne vois rien dans Form1.vb[Design] Je vois juste la forme de l'application quand elle est lancée..

Cordialement.
0
cs_lebuff Messages postés 39 Date d'inscription lundi 15 août 2011 Statut Membre Dernière intervention 17 juillet 2013
19 août 2011 à 13:11
Pour ce qui est du téléchargement j'ai trouvé un code très intéressant qui a l'air de faire pile ce que je veux ici:
http://www.vbfrance.com/code.aspx?ID=41850
C'est la mise à jour du code qu'il avait posté ici:
http://www.vbfrance.com/codes/CLASS-TELECHARGEMENT-HTTP-AVEC-GESTION-RESUME-GESTION-PROXY_27945.aspx
Mais je ne vois pas où déclarer un téléchargement avec son bout de code.
Comme vous me l'aviez dit mettre une barre de progression générale doit être possible en calculant la taille totale des fichiers mais je ne vois pas comment la rajouter après le hash MD5.

Pour ce qui est de la partie comparaison elle fait toujours buger, certaines de ses fonctions (semblables par leur fonctionnement avec DownloadFile sûrement) bloquent l'éxécution du reste du script et cela fait planter directement l'application.
0
Utilisateur anonyme
19 août 2011 à 13:56
Re,
même quand ça ne bug pas on attend un peu avant que le téléchargement ne se lance. La ligne " Dim webrep As WebResponse = webrequest.GetResponse" est souvent citée.

Quelle est le message de l'exception levée ? Timeout ?
Apparemment il y a un problème récurent avec ton serveur distant qui a l'air de n'en faire qu'à sa tête
Sinon je t'ai donné quelque pistes de réflexion, ça ne veut pas dire que ce soit la meilleure solution.
Mais tu n'es vraiment pas loin du but à ce que je vois
Bon courage et bonne prog.
0
cs_lebuff Messages postés 39 Date d'inscription lundi 15 août 2011 Statut Membre Dernière intervention 17 juillet 2013
19 août 2011 à 14:08
Oui l'exception levée est timeout, bizarre parce que mon serveur distant, lorsque je télécharge par internet le fichier, il se lance direct et à très bon débit.
Je pense que je ne vais pas garder la partie que tu m'as passé avec la barre de chargement (pctdownload) parce qu'elle n'est pas pratique a modifier. Je pensais prendre juste la partie téléchargement avec les informations de ce post:
http://www.vbfrance.com/code.aspx?ID=41850

Mais l'architecture de l'application est tout autre, c'est lorsque l'on lance l'application que l'on doit remplir les champs pour le lien mais là aucun problème de timeout quand j'ai testé :)
Je ne sais pas si c'est possible de prendre juste la méthode de téléchargement et de le faire automatiquement dans le script, via le lien vers liste.txt puis via la comparaison.

Mais le plus gros problème que j'ai est que la partie comparaison fait buger l'application maintenant:
L'interface ne se lance pas et j'obtiens une erreur Microsoft.NET Framework Could not find file "C:\Users\...\Debug\liste.txt
Il doit y avoir une autre fonction qui comme DownLoadFile empêche l'exécution du code.
0

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

Posez votre question
Utilisateur anonyme
19 août 2011 à 14:32
Il faut que tu regarde a quel endroit ton nouveau code place le fichier liste.txt téléchargé.
0
cs_lebuff Messages postés 39 Date d'inscription lundi 15 août 2011 Statut Membre Dernière intervention 17 juillet 2013
19 août 2011 à 18:15
Quand j'ai pris la deuxième partie du code que vous m'avez passé j'ai réussi à faire télécharger liste.txt au bon endroit et à créer listelocale.txt aussi au bon endroit mais la partie comparaison fait planter l'application j'ai une erreur juste après que la barre soit à 100% (téléchargement de liste.txt):
WindowsApplication5 a cessé de Fonctionner
Le fichier listelocale.txt est bien créé, le fichier liste.txt est créé mais est vide
L'erreur vient de cette ligne:
Using reader_dist As New IO.StreamReader(Application.StartupPath & "\liste.txt")

The process cannot access the file 'C:\Users\...\Projects\WindowsApplication5\WindowsApplication5\bin\Debug\liste.txt' because it is being used by another process.

On dirait que la partie comparaison n'attend pas que le fichier soit téléchargé entièrement pour se lancer et ce qui fait tout planter.
Voici le code qui plante:

Public Class Form1
    'déclaration du picturebox avec son événement
    Dim WithEvents ProgressB As pctDownload
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'si les fichiers listelocale.txt et liste.txt existent, on les suppriment
        If My.Computer.FileSystem.FileExists(Application.StartupPath & "\listelocale.txt") Then
            My.Computer.FileSystem.DeleteFile(Application.StartupPath & "\listelocale.txt")
        End If
        If My.Computer.FileSystem.FileExists(Application.StartupPath & "\liste.txt") Then
            My.Computer.FileSystem.DeleteFile(Application.StartupPath & "\liste.txt")
        End If

        Dim repertoire() As IO.FileInfo = New IO.DirectoryInfo(Application.StartupPath).GetFiles("*", IO.SearchOption.AllDirectories)
        'écriture de la liste locale des fichiers 
        Using writer As New IO.StreamWriter(Application.StartupPath & "\listelocale.txt", False, System.Text.Encoding.Default)
            For Each fichier As IO.FileInfo In repertoire
                'avec leur nom et leur MD5 séparé par un espace 
                'Note: le choix de l'espace pour la séparation n'est peut-être pas judicieux
                'utiliser New Char() {Convert.ToChar(1)}  pour un meilleur séparateur
                'utilise fichier.FullName pour écrire le chemin complet du fichier
                Dim fichier_p As String = fichier.FullName.Replace(Application.StartupPath, "").Substring(1)
                writer.WriteLine(fichier_p & " " & MD5File(fichier.FullName))
            Next
        End Using
        'instanciation de la classe
        ProgressB = New pctDownload("http://www.monsite.fr/updater/liste.txt", Application.StartupPath & "", 200, 22)

        'ajout de la picturebox au formulaire
        Me.Controls.Add(ProgressB)
        'démarrage du téléchargement
        ProgressB.Start()
    End Sub

    Private Sub ProgressB_Complet(ByVal Fichier As String) Handles ProgressB.Complet 
        'ici tu peux lancer un autre téléchargement ...
        'comparaison...
        Using reader_dist As New IO.StreamReader(Application.StartupPath & "\liste.txt")
            Do While Not reader_dist.EndOfStream
                'lecture de la ligne du fichier
                Dim ligne_dist As String = reader_dist.ReadLine
                'séparation des informations
                Dim fichier_dist As String = ligne_dist.Split(" "c)(0)
                Dim md5_dist As String = ligne_dist.Split(" "c)(1)
                Dim fichier_loc As String = ""
                Using reader_loc As New IO.StreamReader(Application.StartupPath & "\listelocale.txt")
                    Dim fichierexiste As Boolean = False
                    Do While Not reader_loc.EndOfStream
                        Dim ligne_loc As String = reader_loc.ReadLine
                        fichier_loc = ligne_loc.Split(" "c)(0)
                        Dim md5_loc As String = ligne_loc.Split(" "c)(1)
                        'fichiers de même nom
                        If fichier_dist = fichier_loc Then
                            'le md5 est différent
                            If md5_dist <> md5_loc Then
                                Debug.Print("md5 différent : téléchargement de " & fichier_dist)
                                'instanciation de la classe
                                ProgressB = New pctDownload("http://www.monsite.fr/updater/pack/" & fichier_dist, Application.StartupPath & "" & fichier_dist, 200, 22)


                                'ajout de la picturebox au formulaire
                                Me.Controls.Add(ProgressB)
                                'démarrage du téléchargement
                                ProgressB.Start()
                            Else
                                'le hash est le même (on peut effectuer une action ici)
                                Debug.Print("fichier existe (md5 égal) " & fichier_dist)
                            End If
                            fichierexiste = True
                            Exit Do
                        End If
                    Loop
                    'si le fichier n'existe pas on le télécharge
                    If Not fichierexiste Then
                        Debug.Print("fichier introuvable : telechargement de " & fichier_dist)
                        'instanciation de la classe
                        ProgressB = New pctDownload("http://www.monsite.fr/updater/pack/" & fichier_dist, Application.StartupPath & "" & fichier_dist, 200, 22)


                        'ajout de la picturebox au formulaire
                        Me.Controls.Add(ProgressB)
                        'démarrage du téléchargement
                        ProgressB.Start()
                    End If
                End Using
            Loop
        End Using
    End Sub
    'si les fichiers listelocale.txt et liste.txt existent, on les suppriment
    'fonction de hashage MD5
    Private Function MD5File(ByVal nFichier As String) As String
        Dim md5 As New System.Security.Cryptography.MD5CryptoServiceProvider
        Dim fmd5 As New IO.FileStream(nFichier, IO.FileMode.Open, IO.FileAccess.Read)
        md5.ComputeHash(fmd5)
        Dim hash As Byte() = md5.Hash
        Dim buff As System.Text.StringBuilder = New System.Text.StringBuilder
        Dim hashByte As Byte
        For Each hashByte In hash
            buff.Append(String.Format("{0:X2}", hashByte))
        Next
        md5.Clear()
        fmd5.Close()
        fmd5.Dispose()
        Return buff.ToString
    End Function
End Class



Sachant qu'en enlevant la partie comparaison, comme ceci les fichiers sont bien créés sans problème (à part desfois le timeout de temps en temps):

Public Class Form1
    'déclaration du picturebox avec son événement
    Dim WithEvents ProgressB As pctDownload
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'si les fichiers listelocale.txt et liste.txt existent, on les suppriment
        If My.Computer.FileSystem.FileExists(Application.StartupPath & "\listelocale.txt") Then
            My.Computer.FileSystem.DeleteFile(Application.StartupPath & "\listelocale.txt")
        End If
        If My.Computer.FileSystem.FileExists(Application.StartupPath & "\liste.txt") Then
            My.Computer.FileSystem.DeleteFile(Application.StartupPath & "\liste.txt")
        End If
        Dim repertoire() As IO.FileInfo = New IO.DirectoryInfo(Application.StartupPath).GetFiles("*", IO.SearchOption.AllDirectories)
        'écriture de la liste locale des fichiers 
        Using writer As New IO.StreamWriter(Application.StartupPath & "\listelocale.txt", False, System.Text.Encoding.Default)
            For Each fichier As IO.FileInfo In repertoire
                'avec leur nom et leur MD5 séparé par un espace 
                'Note: le choix de l'espace pour la séparation n'est peut-être pas judicieux
                'utiliser New Char() {Convert.ToChar(1)}  pour un meilleur séparateur
                'utilise fichier.FullName pour écrire le chemin complet du fichier
                Dim fichier_p As String = fichier.FullName.Replace(Application.StartupPath, "").Substring(1)
                writer.WriteLine(fichier_p & " " & MD5File(fichier.FullName))
            Next
        End Using
        'instanciation de la classe
        ProgressB = New pctDownload("http://monsite.fr/updater/liste.txt", Application.StartupPath & "", 200, 22)

        'ajout de la picturebox au formulaire
        Me.Controls.Add(ProgressB)
        'démarrage du téléchargement
        ProgressB.Start()
    End Sub

    Private Sub ProgressB_Complet(ByVal Fichier As String) Handles ProgressB.Complet
        'ici tu peux lancer un autre téléchargement ...
    End Sub

  
    'si les fichiers listelocale.txt et liste.txt existent, on les suppriment
    'fonction de hashage MD5
    Private Function MD5File(ByVal nFichier As String) As String
        Dim md5 As New System.Security.Cryptography.MD5CryptoServiceProvider
        Dim fmd5 As New IO.FileStream(nFichier, IO.FileMode.Open, IO.FileAccess.Read)
        md5.ComputeHash(fmd5)
        Dim hash As Byte() = md5.Hash
        Dim buff As System.Text.StringBuilder = New System.Text.StringBuilder
        Dim hashByte As Byte
        For Each hashByte In hash
            buff.Append(String.Format("{0:X2}", hashByte))
        Next
        md5.Clear()
        fmd5.Close()
        fmd5.Dispose()
        Return buff.ToString
    End Function
End Class


Et pour ce qui est du code que j'ai trouvé ici qui marche parfaitement pour le téléchargement :
http://www.vbfrance.com/code.aspx?ID=41850
Sauriez vous comment adapter la partie téléchargement ?
Parce que en fait il fait en 2 parties, une interface nous demande de mettre le lien du fichier à télécharger puis de mettre le répertoire où la mettre puis le téléchargement se fait avec des informations (vitesse, avancement, ect) et une barre de chargement. Ce'st cette dernière partie qui m'intéresse de plus qu'il semble ne plus y avoir aucun problème de timeout.

Cordialement.
0
cs_lebuff Messages postés 39 Date d'inscription lundi 15 août 2011 Statut Membre Dernière intervention 17 juillet 2013
22 août 2011 à 13:27
J'ai résolu pas mal de problèmes maintenant je n'ai plus que deux problèmes qui sont relativement gênants. Le premier est que malgré l'argument overwrite en true je ne peux pas remplacer les fichiers, en effet après la création de la liste, ces fichiers restent ouverts dans l'application ce qui fait qu'on ne peux pas les remplacer.
Et l'autre erreur est que je ne sais pas comment faire pour que la partie comparaison ne se lance qu'une fois le téléchargement terminé du liste.txt sinon cela fait tout planter.
0
cs_lebuff Messages postés 39 Date d'inscription lundi 15 août 2011 Statut Membre Dernière intervention 17 juillet 2013
24 août 2011 à 12:37
A fermer si un modo passe par là. Mauvaise section et autres problèmes.
0
Rejoignez-nous