Bonjours,

J ai déjà créé plusieurs petits programmes en c# (communication PC - Microcontrôleurs etc.), mais j ai jamais eux a utiliser des threads.
Ce sujet a surement déjà été traité, et je m en excuse d en ouvrir un autre mais j ai fait plains de recherches et je n arrive pas a faire marcher le programme avec des threads.

Alors pour mon problème, je suis en train de créer un programme qui copie silencieusement le contenu d'une clé USB sur le disque dure dès qu'on la branche. Ce programme me servira a faire des backup de mes clés USB et disques dures. Au final il sera exécuté sur un vieux pc qui me sert de serveur.

Sans les threads le programme actuel marche très bien il détecte la clé et la copie , le seul problème est que la fenêtre freez pendant la copie des fichier et c est ce que je voudrai éviter.

Alors si quelqu un pourrait m aider a faire fonctionner ce programme avec des threads ça serait super

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
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
using System.Threading;
 
namespace USCOP
{
    public partial class USCOPmain : Form
    {
        // Declaration of global variables
        private const int WM_DEVICECHANGE = 0x0219;
        private const int DBT_DEVICEARRIVAL = 0x8000;
        private const int DBT_DEVICEREMOVECOMPLETE = 0x8004;
        private const int DBT_DEVTYP_VOLUME = 0x2;
 
        public USCOPmain()
        {
            InitializeComponent();
        }
 
        // Recursive copy of the USB drive
        public static void Copie(DirectoryInfo source, DirectoryInfo cible)
        {
            // Check if the directory exists, otherwise it creates
            if (!Directory.Exists(cible.FullName))
            {
                Directory.CreateDirectory(cible.FullName);
            }
 
            // copie chaque fichier dans le nouveau répertoire
            try
            {
                foreach (FileInfo fichier in source.GetFiles())
                {
                    try
                    {
                        fichier.CopyTo(Path.Combine(cible.ToString(), fichier.Name));
                    }
                    catch 
                    { 
                        fichier.CopyTo(Path.Combine(cible.ToString(), fichier.Name)); 
                    }
                }
            }
            catch { }
            try
            {
                // Copie chaque répertoire de la source
                foreach (DirectoryInfo sousRepertoire in source.GetDirectories())
                {
                    // crée un sous-répertoire dans le répertoire cible et rappel la méthode avec comme source un répertoire
                    DirectoryInfo prochaineCible =
                    cible.CreateSubdirectory(sousRepertoire.Name);
                    Copie(sousRepertoire, prochaineCible);
                }
            }
            catch { }
        }
 
        protected override void WndProc(ref Message m)
        {
			// le message est de type DEVICECHANGE, ce qui nous interesse
			if (m.Msg == WM_DEVICECHANGE)
			{
 
				// le "sous-message" dit que le device vient d'etre pluggé
				if (m.WParam.ToInt32() == DBT_DEVICEARRIVAL)
				{
					// device plugged
 
					// on créé une structure depuis un pointeur a l'aide du Marshalling
					// cette structure est generique mais on peut "l'interroger" comme une structure DEV_BROADCAST_HDR
					DEV_BROADCAST_HDR hdr = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_HDR));
 
					// ok, le device pluggé est un volume (aussi appelé 'périphérique de stockage de masse')...
                    if (hdr.dbch_devicetype == DBT_DEVTYP_VOLUME)
                    {
                        // ... et donc on recréé une structure, a partir du même pointeur de structure "générique",
                        // une structure un poil plus spécifique
                        DEV_BROADCAST_VOLUME vol = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_VOLUME));
                        // le champs dbcv_unitmask contient la ou les lettres de lecteur du ou des devices qui viennent d'etre pluggé
                        // MSDN nous dit que si le bit 0 est à 1 alors le lecteur est a:, si le bit 1 est à 1 alors le lecteur est b:
                        // et ainsi de suite
                        uint mask = vol.dbcv_unitmask;
                        // recupèration des lettres de lecteurs
                        char[] letters = MaskDepioteur(mask);
 
                        // mise à jour de l'IHM pour notifier nos petits yeux tout content :)
                        this.textBox1.AppendText("\r\n" + DateTime.Now.Hour.ToString("00") + ":" + DateTime.Now.Minute.ToString("00") + ":" + DateTime.Now.Second.ToString("00") + " --- " + string.Format("USB key plugged on drive {0}:", letters[0].ToString().ToUpper()));
 
                        // Silently copy data from USB key
                        if (Properties.Settings.Default.auto_copy == 1)
                        {
                            this.textBox1.AppendText("\r\n" + DateTime.Now.Hour.ToString("00") + ":" + DateTime.Now.Minute.ToString("00") + ":" + DateTime.Now.Second.ToString("00") + " --- " + "Start Copy files ... (this can take several minutes)");
                            DirectoryInfo lecteurUSB = new DirectoryInfo(letters[0].ToString().ToUpper() + ":\\");
                            DirectoryInfo receptacle = new DirectoryInfo(@Properties.Settings.Default.destination_path + DateTime.Now.Year.ToString("0000") + "_" + DateTime.Now.Month.ToString("00") + "_" + DateTime.Now.Day.ToString("00") + "-" + DateTime.Now.Hour.ToString("00") + "_" + DateTime.Now.Minute.ToString("00") + "_" + DateTime.Now.Second.ToString("00") + @"\");
                            Copie(lecteurUSB, receptacle);
                            this.textBox1.AppendText("\r\n" + DateTime.Now.Hour.ToString("00") + ":" + DateTime.Now.Minute.ToString("00") + ":" + DateTime.Now.Second.ToString("00") + " --- " + "Finish Copy files !");
                        }
                    }
				}
				// le device vient d'etre retirer bourrinement ou proprement
				// (ce message intervient même quand on défait la clef softwarement mais qu'elle reste physiquement branché)
				else if (m.WParam.ToInt32() == DBT_DEVICEREMOVECOMPLETE)
				{
                                        // device removed
 
                                        // mise à jour de l'IHM
                    this.textBox1.AppendText("\r\n" + DateTime.Now.Hour.ToString("00") + ":" + DateTime.Now.Minute.ToString("00") + ":" + DateTime.Now.Second.ToString("00") + " --- " + "USB key unplugged");
                                }
			}
 
			// laissons notre fenêtre faire tout de même son boulot
			base.WndProc(ref m);  
		}
 
		// fonction d'extraction des lettres de lecteur
		public static char[] MaskDepioteur(uint mask)
		{
			int cnt = 0;
			uint temp_mask = mask;
 
			// on compte le nombre de bits à 1
			for (int i = 0; i < 32; i++)
			{
                                if ((temp_mask & 1) == 1)
                                        cnt++;
                                temp_mask >>= 1;
                                if (temp_mask == 0)
                                        break;
                        }
 
			// on instancie le bon nombre d'elements
			char[] result = new char[cnt];
			cnt = 0;
			// on refait mais ce coup ci on attribut
			for (int i = 0; i < 32; i++)
			{
                                if ((mask & 1) == 1)
                                        result[cnt++] = (char)('a' + i);
                                mask >>= 1;
                                if (mask == 0)
                                        break;
                        }
 
			return (result);
		}
 
        private void USCOPmain_Load(object sender, EventArgs e)
        {
            textBox2.Text = Properties.Settings.Default.destination_path;
        }
 
// structure générique
	public struct DEV_BROADCAST_HDR
	{
                public uint dbch_size;
                public uint dbch_devicetype;
                public uint dbch_reserved;
        }
 
	// structure spécifique
	// notez qu'elle a strictement le même tronche que la générique mais
	// avec des trucs en plus
	public struct DEV_BROADCAST_VOLUME
	{
                public uint dbcv_size;
                public uint dbcv_devicetype;
                public uint dbcv_reserved;
                public uint dbcv_unitmask;
                public ushort dbcv_flags;
        }
}
Merci