Appli qui tourne normal sur Visual Studio 2005, et plante quand je lance l'exe s

duteux Messages postés 8 Date d'inscription lundi 3 mai 2004 Statut Membre Dernière intervention 14 mars 2008 - 11 mars 2008 à 18:33
duteux Messages postés 8 Date d'inscription lundi 3 mai 2004 Statut Membre Dernière intervention 14 mars 2008 - 14 mars 2008 à 22:10
Bonjour à tous,

J'ai ecrit une application Windows en C# qui parcour les fichiers *.eml pour en extraire toutes les adresses mails présentes.

Quand je lance l'appli à partir de Visual Studio, tout fonctionne parfait.
0 erreurs
0 avertissements
0 messages

Mais quand je lance l'exe depuis "bin/debug" ou depuis "bin/release", le programme s'ouvre normalement, et dés que je lance la recherche, il se bloque totalement.
La recherche tourne sur un WorkerBackgroung (thread).
C'est la première fois que j'utilise le workerbackground, et c'est aussi la première fois que je rencontre ce genre d'erreur.
Pourtant j'ai respecté à la lettre ce tutorial :
http://glarde.developpez.com/dotnet/bgworker/cs/

toutes les autres appli que j'ai ecrit sur mon PC en VB, C++ ou C# ont toujours fonctionné parfait.

Qu'est ce qui cloche ?
Merci D'avance

///////////////////////////////////////////////////////////

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace WindowsApplication6
{
public partial class Form1 : Form
{
DataSet myDataSet;
double DaCount;
double DaProceed;

public Form1()
{
InitializeComponent();
NewDataTable();
EnableControl(true);
ReadExtensionFile();
}

private void NewDataTable()
{
myDataSet = new DataSet();
DataColumn myDataColumn;

myDataSet.Tables.Add("MAIL");

myDataColumn = new DataColumn();
myDataColumn.DataType = Type.GetType("System.String");
myDataColumn.ColumnName = "Mail add";
myDataSet.Tables["MAIL"].Columns.Add(myDataColumn);
myDataSet.Tables[0].PrimaryKey = new DataColumn[] { myDataColumn };

dataGridView1.AllowUserToOrderColumns = false;
dataGridView1.DataSource = myDataSet.Tables["MAIL"];

//Create Delete button column
DataGridViewButtonColumn ObjBtnCols = new DataGridViewButtonColumn();
ObjBtnCols.HeaderText = "Delete";
ObjBtnCols.UseColumnTextForButtonValue = true;
ObjBtnCols.Text = "Del";
dataGridView1.Columns.Add(ObjBtnCols);

//Enlarge mail column
dataGridView1.Columns[0].Width = 200;
}

public void EnableControl(bool enable)
{
CancelBut.Enabled = !enable;
button3.Enabled = enable;
dataGridView1.Enabled = enable;
}
private void ReadExtensionFile()
{
FileStream file;
StreamReader sr;
string s, fileextensionpath;

//Le fichier extension contient les extensions de mail valid
//Une extension par ligne (com, fr, net, org, be ...)
fileextensionpath = Application.StartupPath + "\\extension.txt";
myDataSet.Tables.Add("extension");
myDataSet.Tables["extension"].Columns.Add();
myDataSet.Tables["extension"].PrimaryKey = new DataColumn[] { myDataSet.Tables["extension"].Columns[0] };

try
{
file = new FileStream(fileextensionpath, FileMode.Open, FileAccess.Read);
sr = new StreamReader(file);
}
catch (Exception ex)
{
MessageBox.Show("Error: Failed to open the Extension file.\nTry re-install the software\n" + ex.Message.ToString());
return;
}
while (!sr.EndOfStream)
{
s = sr.ReadLine();
s = s.Trim();
if (s != "")
myDataSet.Tables["extension"].Rows.Add(new object[] { s });
}
sr.Close();
file.Close();
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
ExtractMail((string)e.Argument, sender, e);
}

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
double d;
//DaProceed: Nbre de fichier déjà lu. DaCount:Nbre de fichier total
d = ((DaProceed)/(DaCount) * 100);
this.progressBar1.Value = e.ProgressPercentage; //Progression du curseur pour un seul fichier
this.progressBar2.Value = (int)d; //Progression sur la lecture de tous les fichiers
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//Kom ca c'est plus beau
progressBar1.Value = 100;
progressBar2.Value = 100;

if (e.Error != null)
{
MessageBox.Show( "Une erreur est survenue ! Détail : " + e.Error.Message);
}
else if (e.Cancelled)
{
MessageBox.Show("Opération annulée !");
}
else
{
dataGridView1.DataSource = myDataSet.Tables[0];
dataGridView1.Refresh();
MessageBox.Show("Opération terminée ! Résultat : " + myDataSet.Tables[0].Rows.Count);
}
EnableControl(true);
}

private void ExtractMail(string thefolder, object sender, DoWorkEventArgs e)
{
DirectoryInfo thedir;
string[] SubDirectories = Directory.GetDirectories(thefolder);
FileInfo[] thefileinfo;
BackgroundWorker worker = sender as BackgroundWorker;

if (SubDirectories.Length == 0)
{
thedir = new DirectoryInfo(thefolder);
thefileinfo = thedir.GetFiles("*.eml");

foreach (FileInfo str in thefileinfo)
{
if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
return;
}
Openfile(str.FullName, worker,e);
DaProceed += 1;
}
}
else
{
for (int i = 0; i < SubDirectories.Length; i++)
{
if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
return;
}
ExtractMail(SubDirectories[i], worker, e);
}
}
}

private void Openfile(string filePath, object sender, DoWorkEventArgs e)
{
string[] token = new string[20];
String s;
string daMail;
FileStream file;
StreamReader sr;
int Total, Percent, Start, End;
double tmp1, tmp2;
bool ignore, thisdone;
BackgroundWorker worker = sender as BackgroundWorker;

try
{
file = new FileStream(filePath, FileMode.Open, FileAccess.Read);
sr = new StreamReader(file);
s = sr.ReadToEnd();
}
catch (Exception ex)
{
MessageBox.Show("Error: Failed to open the selected file.\n" + ex.Message.ToString());
return;
}

Total = s.Length;
//Percent = Total / 100;
Start = 0;
End = 0;
thisdone = false;
ignore = true;
for (int c = 0; c < Total; c++)
{
//worker.ReportProgress
tmp1 = c;
tmp2 = Total;
tmp1 = tmp1 / tmp2 * 100;
Percent = (int)tmp1;

//Pour ne pas rafraichir le ProgressBar1 trop souvent.
if ((Percent % 10) == 0)
{
if (!thisdone)
worker.ReportProgress(Percent);
thisdone = true;
}
else
thisdone = false;

//Si l'utilisateur à cliqué sur "stop"
if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
return;
}

//C'est içi le plus important, la découverte du '@'
if (s[c] == '@')
{
for (int b = c; b >= 0 && b >= c - 20; b--)
{
if (b == c - 20)
Start = b;
if (!isMailChar(s[b]))
{
Start = b + 1;
break;
}
}
for (int a = c; a < Total && a <= c + 25; a++)
{
End = a;
if (!isMailChar(s[a]))
break;
if (s[a] == '.')
{
int i = checkExtension(s.Substring(a + 1, 3));
ignore = false;
if (i == 2)
End = a + 3;
else if (i == 3)
End = a + 4;
else if (i == 0)
ignore = true;
break;
}
else
ignore = true;
}
daMail = s.Substring(Start, End - Start);
daMail = daMail.Trim();
if (!ignore)
AddInDaTable(daMail);
ignore = true;
}
}
sr.Close();
file.Close();
}

public bool isMailChar(char s)
{
// <,>{};/\\#=?!$&%[]:"'|()\t\n
if (s==' '||s=='<'||s==','||s=='>'||s=='{'||s=='}'||s==';'||s=='/'||s=='\\'||s=='#'||s=='='||s=='?'||s=='!'||s=='$'||s=='&'||s=='%'||s=='['||s==']'||s ==':'||s=='"'||s=='\''||s=='|'||s=='('||s==')'||s=='\t'||s=='\n')
return false;
else
return true;
}

//Compte le nombre de fichier à parcourir
private void CountDaFile(string thefolder)
{
DirectoryInfo thedir;
string[] SubDirectories = Directory.GetDirectories(thefolder);
FileInfo[] thefileinfo;

if (SubDirectories.Length == 0)
{
// process this folder
thedir = new DirectoryInfo(thefolder);
thefileinfo = thedir.GetFiles("*.eml");
DaCount += thefileinfo.Length;
}
else
{
for (int i = 0; i < SubDirectories.Length; i++)
CountDaFile(SubDirectories[i]);
}
}

//Ajoute une adresse Mail trouvé à la table de donnée
public void AddInDaTable(string daMail)
{
if (myDataSet.Tables[0].Rows.Find(new object[] { daMail }) == null)
myDataSet.Tables[0].Rows.Add(new object[] { daMail });
}

//Vérifie que aprés le @, une fois le '.' trouvé, que les caracteres suivant
//fassent parti des extensions autorisé par l'utilisateur
private int checkExtension(string s)
{
string strtmp2, strtmp3;

//check for 2
strtmp2 = s.Substring(0, 2);
//MessageBox.Show("check extension: " + strtmp2);
strtmp3 = s.Substring(0, 3);
//MessageBox.Show("check extension: "+ strtmp3);

if (myDataSet.Tables["extension"].Rows.Find(new object[] { strtmp2 }) != null)
{
//Vérifie dans la table de donnée extension sir les 2 caracteres suivant le '.' sont présent
return 2;
}
else if (myDataSet.Tables["extension"].Rows.Find(new object[] { strtmp3 }) != null)
{
//Vérifie dans la table de donnée extension sir les 2 caracteres suivant le '.' sont présent
return 3;
}
else
return 0;
}

private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
DataRow therow;
string strRow;
if (e.ColumnIndex == 0) //Click sur le bouton Delete
{
strRow = dataGridView1.Rows[e.RowIndex].Cells[1].Value.ToString();
therow = myDataSet.Tables[0].Rows.Find(new object[] { strRow });
if (therow != null)
myDataSet.Tables[0].Rows.Remove(therow);
dataGridView1.DataSource = myDataSet.Tables[0];
dataGridView1.Refresh();
}
}

private void button2_Click(object sender, EventArgs e) //Stop la recherche
{
backgroundWorker1.CancelAsync();
}
private void stopperLextractionToolStripMenuItem_Click(object sender, EventArgs e)//Stop la recherche
{
backgroundWorker1.CancelAsync();
}

private void button3_Click(object sender, EventArgs e) //Efface la table
{
myDataSet.Tables[0].Clear();
dataGridView1.DataSource = myDataSet.Tables[0];
dataGridView1.Refresh();
}



private void ajouterExtensionToolStripMenuItem_Click(object sender, EventArgs e)
{
//add extension to file extension
}

private void listeDesExtensionsToolStripMenuItem_Click(object sender, EventArgs e)
{
//open form2 to see mail extension list.
}

private void extraireDepuisUnDossierToolStripMenuItem1_Click(object sender, EventArgs e)
{
string folderPath;
int day, hour, minute, seconde, temp;
DaCount = 0;

folderBrowserDialog1.SelectedPath = "c:\\users\" + Environment.UserName + "\\appdata\\local\\microsoft\\windows mail\\local folders\";
folderBrowserDialog1.ShowDialog();
folderPath = folderBrowserDialog1.SelectedPath.ToString();

CountDaFile(folderPath); //Compte le nombre de fichier qu'on va parcourir

if (DaCount > 0)
{
temp = (int)(DaCount * 2);
seconde = temp % 60;
temp = (int)(DaCount * 2 / 60);
minute = temp % 60;
temp = (int)(DaCount * 2 / 3600);
hour = temp % 24;
temp = (int)(DaCount * 2 / (3600 * 24));
day = temp;
}
else
{
day = 0;
hour = 0;
minute = 0;
seconde = 0;
}
if (MessageBox.Show("Number of files : " + DaCount + "\nEstimated time : " + day + "d " + hour + "h " + minute + "m " + seconde + "s\nProceed ?", "\nProceed ?", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
DaProceed = 0;
EnableControl(false);
backgroundWorker1.RunWorkerAsync(folderPath); //lance la recherche
}
}

private void vaFanCuloToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("bon allez contact moi à duteux@hotmail.com");
}

private void effacerGrilleToolStripMenuItem_Click(object sender, EventArgs e)
{
myDataSet.Tables[0].Clear();
dataGridView1.DataSource = myDataSet.Tables[0];
dataGridView1.Refresh();
}

private void quitterToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();//Form1.
}

private void auFormatTexteToolStripMenuItem_Click(object sender, EventArgs e)
{
saveFileDialog1.Filter = "Text File (*.txt)|*.txt";
saveFileDialog1.FileName = "";
saveFileDialog1.ShowDialog();
SaveMailToTXT(saveFileDialog1.FileName);
}
private void SaveMailToTXT(string Filename)
{
// Specify file, instructions, and privelegdes
FileStream file = new FileStream(Filename, FileMode.OpenOrCreate, FileAccess.Write);

// Create a new stream to write to the file
StreamWriter sw = new StreamWriter(file);

//Accessibility the Data
DataRowCollection dra = myDataSet.Tables["MAIL"].Rows;

foreach (DataRow dr in dra)
{
sw.WriteLine(dr[0]);
}

sw.Close();
file.Close();
}

private void Form1_SizeChanged(object sender, EventArgs e)
{
dataGridView1.Width = Form1.ActiveForm.Width - 40;
dataGridView1.Height = Form1.ActiveForm.Height - 128;
}
}// End of Class Form1
}// End of Namespace WindowsApplication6

5 réponses

taupe4 Messages postés 91 Date d'inscription dimanche 16 avril 2006 Statut Membre Dernière intervention 17 avril 2008 1
12 mars 2008 à 01:21
Le fichier ici: fileextensionpath = Application.StartupPath + "\\extension.txt";
Est-ce qu'il est dans bin/release et dans bin/debug ?

2."c:\\users\" + Environment.UserName + "\\appdata\\local\\microsoft\\windows mail\\local folders\". Tu es sous vista, as-tu accès à ce dossier ? Essaie de démarrer ton programme avec l'UAC désactivé (clicdroit->éxécuter en tant qu'administrateur). P.S. Essaie Path.Combine( Environment.GetFolderPath(Environment.SpecialFolders.LocalApplicationData), "microsoft\\windows mail\\local folders\");
0
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
12 mars 2008 à 10:03
bonnes questions de taupe...
Visual studio doit tourner avec les droits d'admin... du coups en debug tu n'as pas de souci...

Sébastien FERRAND (blog)
Consultant Indépendant
[Microsoft Visual C# MVP]
0
duteux Messages postés 8 Date d'inscription lundi 3 mai 2004 Statut Membre Dernière intervention 14 mars 2008
12 mars 2008 à 15:28
Salut,

Merci Taupe4 pour ta réponse.
1. Oui le fichier est bien dans le bon répertoire. Si il n'y était pas, j'aurais une exception dans le "try catch" et comme ca s'ouvre au lancement et que le programme n'est pas bloqué du moment que je ne lance pas la recherche. Donc ce n'est pas ça.
2. Quand je clique sur "extraire", le logiciel ouvre le FolderBrowserDialog directement dans le bon repertoire que je lui ai indiqué, donc ca aussi c'est bon.

Par contre y'a un truc bizar qui se passe quand je lance l'extraction, c'est que directement (au bout de 2 ou 3 secondes) il m'affiche dans mon datagrid une dizaine d'adresse mail (ce qui prouve qu'il arrive a lire les mails, dans le bon répertoire, et qu'il a pu acceder a extension.txt pour trier ces adresses mails). Normalement il est censé passer 15 minutes dessus, et m'afficher toutes les adresses trouvé à la fin.
0
duteux Messages postés 8 Date d'inscription lundi 3 mai 2004 Statut Membre Dernière intervention 14 mars 2008
12 mars 2008 à 15:32
j'ai aussi essayé de l'executer en administrateur, et même probleme.
0

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

Posez votre question
duteux Messages postés 8 Date d'inscription lundi 3 mai 2004 Statut Membre Dernière intervention 14 mars 2008
14 mars 2008 à 22:10
Salut,

C'est bon, j'ai réussi a corriger le probleme.
En fait c'est le datagridView qui se fesait rafraichir trop souvent par le processus.
il semblerait que le datagridView se rafraichi tout seul quand la table de donnée source est modifiée.
J'ai donc crée une table Temporaire dans le backgroundWorker, et a la fin de la recherche, je recopie la table dans la vrai table (celle qui s'affiche dans le dataGridView1)

Maintenant ça tourne nikel !!!
merci quand même.
0
Rejoignez-nous