MGD Software
Messages postés193Date d'inscriptionvendredi 1 septembre 2006StatutMembreDernière intervention23 avril 2022
-
26 mars 2019 à 12:24
MGD Software
Messages postés193Date d'inscriptionvendredi 1 septembre 2006StatutMembreDernière intervention23 avril 2022
-
1 avril 2019 à 10:24
Bonjour,
Après avoir écumé les forums les plus divers, je n'arrive toujours pas à envoyer un mail depuis que tous les fournisseurs d'accès chez qui j'ai un compte ont imposé le SMTP authentifié.
Comme j'ai plus de 25 boites à lettres, j'ai essayé au moins une adresse chez Free, SFR, Gmail, Hostinger, Online, toujours sans résultats.
Le diagnostic est toujours le même : délai de connexion dépassé.
Je précise que les informations de connexion fonctionnent parfaitement avec Outlook.
Je joins le code de la fonction qui envoie le mail. Ce mail est envoyé par cette appli sur mon serveur local à chaque changement d'IP (elle est dynamique, hélas). Enfin, quand ça marche...
Quelques précisions :
- La classe ProfileString reproduit l'ancien fonctionnement des fonctions homonymes chères à Windows 95 et me permet de stocker facilement des paramètres hors de la base de registre (le fameux fichier ".ini") et à l'endroit que JE souhaite.
- les paramètres SMTP authentifié ont été vérifiés. De plus, pour Gmail, le mot de passe est un mot de passe d'application, spécifique pour les applications "non sécurisées" (Google dixit). En règle générale, le port utilisé est le 465, et le SSL est activé. Le serveur est smtp.xxx (smtp.free.fr, smtp.sfr.fr, smtp.gmail.com, mx1.hostinget.fr, smtp.hostinger.fr, smtp.online.net, etc.).
- Les destinataires peuvent être plusieurs, ce qui explique la boucle dans le tableau Dests. Ces destinataires peuvent être ou non validés.
- Le corps du message est un texte modèle comportant des marqueurs, remplacés par leur valeur lors de l'envoi du mail.
voici le code de la fonction :
private bool SendIP()
{
SmtpClient Client = new SmtpClient();
MailMessage Mail = new MailMessage();
try
{
// Paramètres de connexion
Client.Host = ProfileString.GetIniParam("Options", "EmailHost", "");
Client.Port = (int)ProfileString.GetIniParam("Options", "EmailPort", 0);
Client.EnableSsl = ProfileString.GetIniParam("Options", "EmailSSL", true);
Client.DeliveryMethod = SmtpDeliveryMethod.Network;
Client.Timeout = 30000; // 30 secondes par défaut
string User = ProfileString.GetIniParam("Options", "EmailUser", "");
string Pwd = Crypt.CryptOff(ProfileString.GetIniParam("Options", "EmailPwd", ""), CrypKey);
if (User != "" || Pwd != "")
{
Client.UseDefaultCredentials = false;
//Client.UseDefaultCredentials = true;
Client.Credentials = new NetworkCredential(User, Pwd);
}
else
Client.UseDefaultCredentials = true;
Mail.BodyEncoding = UTF8Encoding.UTF8;
Mail.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;
// Adresse origine
string FromAdrs = ProfileString.GetIniParam("Options", "EamilFromAdrs", "");
string FromName = ProfileString.GetIniParam("Options", "EmailFromName", "");
Mail.From = new MailAddress(FromAdrs, FromName);
Mail.Sender = new MailAddress(FromAdrs, FromName);
// Destinataires
string[] Dests = ProfileString.GetIniParamsList("Emails");
string DefMails = "";
foreach (string Dest in Dests)
{
string[] Dummy = ProfileString.GetIniParam("Emails", Dest, "").Split('|');
string MailAdrs = Dummy[0];
bool Enabled = false;
if (Dummy.Length > 1)
Enabled = Dummy[1] == "1";
if (Enabled )
{
if (IsValidMail(MailAdrs))
Mail.To.Add(MailAdrs);
else
DefMails += "\n" + MailAdrs;
}
}
// Sujet et corps
string Body = MgdDiv.Base64Decode(ProfileString.GetIniParam("Options", "EmailText", ""));
Body = Body.Replace("[$IP$]", lblIpAddress.Text);
Body = Body.Replace("[$DATE$]", DateTime.Now.ToShortDateString());
Body = Body.Replace("[$TIME$]", DateTime.Now.ToLongTimeString());
Mail.Subject = ProfileString.GetIniParam("Options", "EmailSubject", "");
Mail.Body = Body;
// Armement du timer de rappel en cas d'exception lors de l'envoi
lblLastTrans.Text = "";
tmrSend.Enabled = true;
// Envoi du message
this.Cursor = Cursors.WaitCursor;
Client.Send(Mail);
tmrSend.Enabled = false; // Envoi ok : on annule le renvoi
this.Cursor = Cursors.Default;
lblLastTrans.Text = DateTime.Now.ToString("G");
if (DefMails != "")
{
string Prompt = "Les destinataires suivants présentent une erreur : " + DefMails;
if (this.Visible)
MessageBox.Show(Prompt, "Envoi de mail", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
return true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Erreur d'envoi", MessageBoxButtons.OK, MessageBoxIcon.Error);
this.Cursor = Cursors.Default;
return false;
}
}
La gestion de l'utilisateur et du mot de passe est-elle correcte ? (j'ai un doute concernant le Client.UseDefaultCredentials, la doc Microsoft n'est pas du tout claire là-dessus). Mais j'ai essayé true et false, et le résultat est le même.
Est-ce que j'aurais oublié un paramètre ??
Est-il possible d'avoir un diagnostic plus précis que le "délai dépassé" ? J'ai cherché dans les propriétés de Client et de Mail dans le traitement de l'exception, mais rien d'autre que le message d'erreur lui-même ("Le délai d'attente de l'opération a expiré."), ou le status de l'exception "General failure".
ThePearl98
Messages postés1Date d'inscriptionlundi 1 avril 2019StatutMembreDernière intervention 1 avril 2019 1 avril 2019 à 01:19
Salut Mr. J'utilises Ubuntu 18 LTS , j'ai essayé ton code sur V_MACHINE Windows 7, VS 2008 .NET 2.0 en utilisant Tcl et j'ai toujours ce message immédiatement :
Unhandled Exception: System.Net.Mail.SmtpException: The operation has timed out
at Exception.Handle :line 29
J'ai ajouté
1.nouvelle variable pour l utiliser en Bloc Try :
var task = Task.Factory.StartNew(() => SendEmail(email));
if (!task.Wait(6000))
// error handling for timeout on TCP layer (but you don't get the exception object)
2. un 2éme bloc catch :
using (var client = new SmtpClient(_serverCfg.Host, _serverCfg.Port))
{
try
{
client.Timeout = 5000; // shorter timeout than the task.Wait()
// ...
client.Send(msg);
}
catch (Exception ex)
{
// exception handling
}
}
MGD Software
Messages postés193Date d'inscriptionvendredi 1 septembre 2006StatutMembreDernière intervention23 avril 20222 Modifié le 1 avril 2019 à 10:28
Bonjour,
Cette exception de timeout est bien le cœur du problème.
Pour ma part, elle est traitée au niveau supérieur, dans la fonction appelante.
Après de multiples essais, j'ai enfin réussi une connexion sur le serveur de Gmail, en validant la double authentification, en utilisant un mot de passe "application" et le port 587 en SSL.
Donc à priori le problème ne provient pas du code : s'il marche pour un serveur, il devrait fonctionner pour les autres. J'ai pourtant vérifié tous les paramètres de ces derniers. Et même Gmail, avec le mot de passe standard de messagerie, ne fonctionne pas alors que ça marche avec Outlook à partir de la même IP (mais pas du même poste).
Il est possible qu'avec la paranoïa actuelle des serveurs de messagerie, il y ait un contrôle du contenu des messages et que le serveur détecte si le mail provient d'une machine et non d'un logiciel de messagerie. Ce qui voudrait dire que ces derniers formatent le message de façon spécifique. Je n'ai rien trouvé à ce sujet sur la toile, mais peut-être que j'ai trop d'imagination.
En attendant, mon appli fonctionne mais c'est quand même bizarre que les serveurs ne répondent pas, quitte à envoyer un message de rejet.