C# SMTP Access Problem - c#

I`m working with C# using the libraries
using System.Net.Mail;
using System.Windows;
I want to use the code in many places, ie. place A, place B, place C ...
when I use it at place A, it works and mails are sent from my application.
but when I use it at place B, place C ... nothing is sent and I get errors, I want to know how to solve it.
this is my class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Mail;
using System.Windows;
namespace Send_Mail_WPF_
{
class SendMail
{
private string fromAddress;
private string fromPassword;
private string toAddress;
private string msgSubject;
private string msgBody;
private string exchangeServer;
private int exchangeServerPort;
private bool error;
private MailMessage message;
SmtpClient client;
public SendMail(string fromMail, string toMail, string fromPass, string subject, string body)
{
error = false;
try
{
fromAddress = fromMail.ToString();
toAddress = toMail.ToString();
fromPassword = fromPass.ToString();
msgSubject = subject.ToString();
msgBody = body.ToString();
exchangeServer = #"smtp.tedata.net";
exchangeServerPort = 25;
initializeMessage();
setSMTPClient();
}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString());
errorFound = true;
}
}
public bool errorFound
{
set
{
error = value;
}
get
{
return error;
}
}
private void initializeMessage()
{
message = new MailMessage(fromAddress, toAddress);
message.Subject = msgSubject;
message.Body = msgBody;
message.IsBodyHtml = false;
}
private void setSMTPClient()
{
try
{
client = new SmtpClient(exchangeServer, exchangeServerPort);
client.EnableSsl = false;
client.Credentials = new NetworkCredential(fromAddress, fromPassword);
MessageBox.Show("From" + message.From.ToString());
message.From = new MailAddress("aaaaaaaa#aaaaaaaaaaaaa.com");
MessageBox.Show("From" + message.From.ToString());
Application.Current.Shutdown();
}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString());
errorFound = true;
}
}
public void sendMessage()
{
try
{
client.Send(message);
}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString());
errorFound = true;
}
}
}
}
I think the problem is in the exchange server, but I don`t know how to over come this.
EDIT:
ERROR I get from any location rather than place A
alt text http://img651.imageshack.us/img651/6343/errorh.jpg

By the different places, I take it you mean different machines. The problem is likely DNS, or some other problem external to your code. A good way to test SMTP connectivity is to telnet to smtp.tedata.net on port 25. I'm guessing that won't work, which explains why your code doesn't work either. Once you've solved the network issue, retry your code.

Your code is OK. This is probably an authentication issue. Check with your network administrator.

Difference places means different Ip address.
sometimes SMTP service is set to work only in limited ip pool.
In your case, it is likely your SMTP service would only work in Place A's IP address, but not in Place B, and Place C

Related

C# if statement not working

My code works within a local network and I know it will not work outside of the local network as I am using Dns.GetHostEntry to resolve the IP address to hostname and thats fine...
But my if statement is not working, I am getting error "No Host Found" message when trying to resolve hostname from different subnet.
I thought my if statement would stop this error but its not working, can someone help please or tell me how to fix it, code below...
public partial class _Default : System.Web.UI.Page
{
//public string IPaddr1 { get; private set; }
string serviceDesk = "eg#mail.co.uk";
string emailSubject = "MyPc";
string IPaddr = "";
string deviceName = "";
protected void Page_Load(object sender, EventArgs e)
{
getIP();
}
protected void getIP()
{
if (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDER_FOR"] != null)
{
IPaddr = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDER_FOR"].ToString();
}
if (HttpContext.Current.Request.UserHostAddress.Length != 0)
{
IPaddr = HttpContext.Current.Request.UserHostAddress;
deviceName = Dns.GetHostEntry(IPAddress.Parse(IPaddr)).HostName;
}
if (HttpContext.Current.Request.UserHostAddress.Length != 0)
{
deviceName = "Device name could be found";
}
Label1.Text = "IP Address: " + " " + IPaddr;
Label2.Text = "PC Name: " + " " + deviceName;
}
private void EmailVerificationRequest(string recepientEmail, string subject)
{
try
{
using (MailMessage mailMessage = new MailMessage())
{
StringBuilder sbEmailBody = new StringBuilder();
sbEmailBody.Append("IP address " + IPaddr + "<br/>");
sbEmailBody.Append("Hostname " + " " + deviceName);
mailMessage.From = new MailAddress(ConfigurationManager.AppSettings["FromEmail"]);
mailMessage.Subject = subject;
mailMessage.Body = sbEmailBody.ToString();
mailMessage.IsBodyHtml = true;
mailMessage.To.Add(new MailAddress(recepientEmail));
SmtpClient smtp = new SmtpClient();
smtp.Host = ConfigurationManager.AppSettings["Host"];
smtp.Port = Convert.ToInt32(ConfigurationManager.AppSettings["Port"]);
smtp.EnableSsl = Convert.ToBoolean(ConfigurationManager.AppSettings["EnableSsl"]);
System.Net.NetworkCredential NetworkCred = new System.Net.NetworkCredential();
NetworkCred.UserName = ConfigurationManager.AppSettings["UserName"];
NetworkCred.Password = ConfigurationManager.AppSettings["Password"];
if (string.IsNullOrWhiteSpace(NetworkCred.UserName))
{
smtp.UseDefaultCredentials = true;
}
else
{
smtp.Credentials = NetworkCred;
smtp.UseDefaultCredentials = false;
}
smtp.Port = int.Parse(ConfigurationManager.AppSettings["Port"]);
try
{
smtp.Send(mailMessage);
}
catch (SmtpException e)
{
}
}
}
catch
{
}
}
protected void Button1_Click(object sender, EventArgs e)
{
EmailVerificationRequest(serviceDesk, emailSubject);
Response.Redirect("~/message.aspx");
}
}
From the MSDN Documentation:
If the host name could not be found, the SocketException exception is returned with a value of 11001 (Windows Sockets error WSAHOST_NOT_FOUND). This exception can be returned if the DNS server does not respond. This exception can also be returned if the name is not an official host name or alias, or it cannot be found in the database(s) being queried.
Therefore, I suspect your code isn't getting as far as the third if condition because an exception is being thrown by the call to GetHostEntry(), which you're seeing as the 'error "No Host Found" message'.
The most straightforward way to deal with this is to use a try...catch block to catch the specific exception and handle it, something such as:
try
{
deviceName = Dns.GetHostEntry(IPAddress.Parse(IPaddr)).HostName;
}
catch (SocketException)
{
deviceName = "Device name could be found";
}
This says that if a SocketException occurs during the call to GetHostEntry(), the code is to jump to the catch block, rather than the exception stopping your application.
Note that this assumes that any SocketException means that the IP address wasn't found, but it could mean that the DNS server wasn't contactable, or some other error.
MSDN has quite a lot on exception handling and how try...catch blocks work.
Hope this helps
Before you get a value from a dictionary, you must check if the dictionary contains the key you pass. You achieve this by calling "Contains" method.
if (HttpContext.Current.Request.ServerVariables.Contains("HTTP_X_FORWARDER_FOR"))
{
// Your Code...
}
If you retrieve the content of a dictionary directly and the key you are requesting doesn't exist in the dictionary pairs, the dictionary doesn't return null. Instead, it throws KeyNotFoundException.

Memory leak is seen when SmtpClient send function called multiple times

I have to send mails multiple times, when this is done multiple times by using smtpclient class, Memory is increasing drastically......
I have tried with following things...
- Calling dispose methods for MailMessage, smtpclient
- calling GC.collect method manually
Nothing helped me...
using System;
using System.Net.Mail;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
MailMessage mail = new MailMessage();
using (var smtpobj = new SmtpClient("smtp.gmail.com"))
{
mail.To.Add("xxx#gmail.com");
mail.From = new MailAddress("yyy#gmail.com");
mail.Subject = "subject - .net app";
mail.Body = "body";
smtpobj.Port = 587;
smtpobj.Credentials = new System.Net.NetworkCredential("yyy#gmail.com", "xyz");
smtpobj.EnableSsl = true;
smtpobj.Send(mail);
}
}
catch(Exception ex)
{
string strReturn = ex.ToString();
MessageBox.Show(strReturn);
}
}
}
}
Try the following:
using System;
using System.Net.Mail;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
MailMessage mail = new MailMessage();
using (var smtpobj = new SmtpClient("smtp.gmail.com"))
{
mail.To.Add("xxx#gmail.com");
mail.From = new MailAddress("yyy#gmail.com");
mail.Subject = "subject - .net app";
mail.Body = "body";
smtpobj.Port = 587;
smtpobj.Credentials = new System.Net.NetworkCredential("yyy#gmail.com", "xyz");
smtpobj.EnableSsl = true;
smtpobj.Send(mail);
smtpobj.ServicePoint.CloseConnectionGroup(
smtpobj.ServicePoint.ConnectionName);
}
}
catch(Exception ex)
{
string strReturn = ex.ToString();
MessageBox.Show(strReturn);
}
}
}
}
This is per: https://social.msdn.microsoft.com/Forums/vstudio/en-US/28b59c25-bc93-4285-860d-52f1f49d2d43/net-smtp-class-memory-leakage?forum=netfxbcl

How to connect to instrument through USB using c#

I am trying to use the Ivi.Visa.Interop .dll to communicate to a Voltech PM1000+ power meter using USB. I'm relatively new to C# and do not know really where to start. I am using Visual Studio 2015 Community. I have already talked to a different instrument using GPIB and here is the code for that:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Ivi.Visa.Interop;
namespace commOverIP
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void InitiateIOBtn_Click(object sender, EventArgs e)
{
///testing out excel
InitiateIOBtn.Text = "Initializing";
try
{
// resource manager and message-based session manager
Ivi.Visa.Interop.ResourceManager mngr = new Ivi.Visa.Interop.ResourceManager();
// GPIB address
string srcAddress = "GPIB::27::INSTR"; // GPIB address of data acquisition
//setting up communication
Ivi.Visa.Interop.FormattedIO488 instrument = new Ivi.Visa.Interop.FormattedIO488();
Ivi.Visa.Interop.IMessage Imsg = (mngr.Open(srcAddress, Ivi.Visa.Interop.AccessMode.NO_LOCK, 1000, "") as IMessage);
instrument.IO = Imsg;
instrument.IO.Clear();//clear io buffer
instrument.WriteString("*RST", true);//send RST? command to instrument
instrument.WriteString("*IDN?", true);//send IDN? command to instrument
returnOfCommand.Text = instrument.ReadString();//read IDN? result
//close communication
instrument.IO.Close();
System.Runtime.InteropServices.Marshal.ReleaseComObject(instrument);
System.Runtime.InteropServices.Marshal.ReleaseComObject(mngr);
InitiateIOBtn.Text = "Initialize I/O";
//*/
}
catch(Exception exp)
{
MessageBox.Show(exp.Message);
}
InitiateIOBtn.Text = "Initialize I/O";
}
}
}
This works fine but USB seems to be a different beast. The only real lead I found was in the .dll with the:
IUsb.Init(string, Ivi.Visa.Interop.AccessMode, int, string)
I tried implementing this but I don't really know where to start.
If anyone could give me an example of how to query a "*IDN?" command that would be great. Or, even if there is a better way of doing this than through the Ivi.Visa.Interop dll.
Thanks in advance
Restart your device once. Clearing the IO also helps. Afterwards following code should work fine:
string resourceString= "USB0::xxx::xxx::xxx::0::INSTR";
ResourceManager manager = new ResourceManager();
FormattedIO488 connection = new FormattedIO488();
connection.IO = (IMessage)manager.Open(resourceString, AccessMode.NO_LOCK, 0, "");
connection.IO.Clear();
connection.WriteString("*IDN?", true);
string result = connection.ReadString();
I do what you are asking all of the time and I completely understand how frustrating it can be. I remember doing Google searches to come up with this code. The code actually came from some Keysight documentation when I bought the Agilent 82357B USB/GPIB Controller.
This can be adapted for any GPIB instrument, the only difference being the strings that you send to the instrument. These can be obtained by getting the programming manual for the instrument in which you're interested.
I installed the Keysight (formerly Agilent) I/O Library Suites that is used with the Agilent 82357B. One thing that is not obvious is that you should disable the 'Auto Discovery' option, as this feature will occasionally put your device in Local mode.
using System.Threading;
using System.Runtime.InteropServices;
// Add reference for VISA-COM 5.9 Type Library
using Ivi.Visa.Interop;
namespace USBCommunications
{
class Program
{
static void Main(string[] args)
{
Gpib.Write(address: 5, command: "*IDN?");
bool success = Gpib.Read(address: 5, valueRead: out string valueRead);
System.Console.WriteLine($"The ID is {valueRead}");
System.Console.ReadLine();
}
}
public class Gpib
{
static ResourceManager resourceManager;
static FormattedIO488 ioObject;
public static bool Write(byte address, string command)
{
resourceManager = new ResourceManager();
ioObject = new FormattedIO488();
string addr = $"GPIB::{address.ToString()}::INSTR";
try
{
ioObject.IO = (IMessage)resourceManager.Open(addr, AccessMode.NO_LOCK, 0, "");
Thread.Sleep(20);
ioObject.WriteString(data: command, flushAndEND: true);
return true;
}
catch
{
return false;
}
finally
{
try { ioObject.IO.Close(); }
catch { }
try { Marshal.ReleaseComObject(ioObject); }
catch { }
try { Marshal.ReleaseComObject(resourceManager); }
catch { }
}
}
public static bool Read(byte address, out string valueRead)
{
resourceManager = new ResourceManager();
ioObject = new FormattedIO488();
string addr = $"GPIB::{address.ToString()}::INSTR";
try
{
ioObject.IO = (IMessage)resourceManager.Open(addr, AccessMode.NO_LOCK, 0, "");
Thread.Sleep(20);
valueRead = ioObject.ReadString();
return true;
}
catch
{
valueRead = "";
return false;
}
finally
{
try { ioObject.IO.Close(); }
catch { }
try { Marshal.ReleaseComObject(ioObject); }
catch { }
try { Marshal.ReleaseComObject(resourceManager); }
catch { }
}
}
}
}
Happy programming!!

How can i make that my application will check and get specific email subject?

I have this class that send emails. I log in using my isp email and send it to my gmail email.
Now i want to do that when someone will download/get my application it will check each 1 minute for my gmail account address for a specific email with a specific subject so the email subject will be like a code for example the email subject will be: 16765645
Once the application downloaded the email i want to display the email content in a textBox and also to write on a text file the email content. Also i want that the application will check the email time download after it was downloaded so the application will not download the same email all the time.
This is how i'm sending emails today:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DannyGeneral;
using System.Net.Mail;
using System.Net;
using System.Net.Mime;
using System.IO;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;
namespace Diagnostic_Tool_Blue_Screen
{
class SendEmail
{
private MailMessage photosmessage;
public bool textfilessendended;
public bool photossendended;
Label lbl1;
Label lbl3;
Button SendLogFile;
MailMessage message;
MailMessage docmessage;
public int timerdelay;
public Timer timer3;
public SendEmail(Label label2, Label label3, Button slf, int timerd, Timer timer)
{
textfilessendended = false;
photossendended = false;
lbl1 = label2;
lbl3 = label3;
SendLogFile = slf;
timerdelay = timerd;
timer3 = timer;
}
public void SendLogger()
{
string log_file_name = "logger.txt";
string logger_file_to_read = Path.GetDirectoryName(Application.LocalUserAppDataPath) + #"\log";
string LoggerFile = Path.Combine(logger_file_to_read, log_file_name);
try
{
MailAddress from = new MailAddress("test#gmail.com", "User " + (char)0xD8 + " Name",
System.Text.Encoding.UTF8);
MailAddress to = new MailAddress("test#test.net");
message = new MailMessage(from, to);
message.Body = "Please check the log file attachment i have some bugs.";
string someArrows = new string(new char[] { '\u2190', '\u2191', '\u2192', '\u2193' });
message.Body += Environment.NewLine + someArrows;
message.BodyEncoding = System.Text.Encoding.UTF8;
message.Subject = "Log File For Checking Bugs" + someArrows;
message.SubjectEncoding = System.Text.Encoding.UTF8;
Attachment myAttachment = new Attachment(LoggerFile, MediaTypeNames.Application.Octet);
message.Attachments.Add(myAttachment);
SmtpClient ss = new SmtpClient("smtp.gmail.com", 587);
ss.SendCompleted += new SendCompletedEventHandler(ss_SendCompleted);
ss.EnableSsl = true;
ss.Timeout = 10000;
ss.DeliveryMethod = SmtpDeliveryMethod.Network;
ss.UseDefaultCredentials = false;
ss.Credentials = new NetworkCredential("meuser", "mepassword");
string userState = "test message1";
ss.SendAsync(message, userState);
lbl3.Enabled = true;
lbl3.Visible = true;
lbl3.BackColor = Color.DarkSeaGreen;
lbl3.Text = "Sending email please wait";
SendLogFile.Enabled = false;
}
catch (Exception errors)
{
Logger.Write("Error sending message :" + errors);
}
}
private void ss_SendCompleted(object sender, AsyncCompletedEventArgs e)
{
timerdelay = 0;
timer3.Start();
String token = (string)e.UserState;
if (e.Cancelled)
{
Logger.Write("[{0}] Send canceled." + token);
SendLogFile.Enabled = true;
}
if (e.Error != null)
{
lbl3.Enabled = true;
lbl3.Visible = true;
lbl3.BackColor = Color.DarkSeaGreen;
lbl3.Text = "There was a problem with sending the log file please try again later and check the log file for more information";
Logger.Write("There was a problem with sending the log file please try again later and check the log file for more information :" + e.Error.ToString());
SendLogFile.Enabled = true;
}
else
{
SendLogFile.Enabled = true;
message.Dispose();
lbl3.Enabled = true;
lbl3.Visible = true;
lbl3.BackColor = Color.DarkSeaGreen;
lbl3.Text = "Email have been sent successfully";
Logger.Write("Attached log file have been emailed successfully");
lbl1.BringToFront();
lbl1.Visible = true;
lbl1.Text = "The log file have been sent on: " + DateTime.Now;
}
}
The idea in general is to use the email like a server to transfer a push messages like updates. So when a user is downloading my program and run if any X minutes there a new email he will see it in the program like a new update.
The idea in general is to use the email like a server to transfer a push messages like updates. So when a user is downloading my program and run if any X minutes there a new email he will see it in the program like a new update.
Honestly, this sounds more like a job for a web service than an email client. You can have your client periodically consume a web service that publishes the latest update message. It will be much simpler for you to implement, and there is a plethora of documentation for doing so.
If you let web services do all the heavy lifting for you, you'll have less code to write, and have to worry less about making a secure, stable solution. Using email to do this seems very kludgy.

How to authenticate the password in an email application built on windows forms?

Yesterday, i had a task assigned by my senior to build a windows forms application in .net which looked like the image i attached. I did all the stuff regarding the sending process of the email application, but i stuck at one place, i couldn't figure out how to authenticate the password in the email form. The password must be of the same email, which was provided in the "From :" fields.
Here is the code behind of my form,
public partial class Form1 : Form
{
MailMessage message;
SmtpClient smtp;
public Form1()
{
InitializeComponent();
lbl_Error.Visible = false;
}
private void chk_Show_Password_CheckedChanged(object sender, EventArgs e)
{
if (chk_Show_Password.Checked == true)
txt_Password.PasswordChar= '\0';
else
txt_Password.PasswordChar='*';
}
private void btn_Send_Click(object sender, EventArgs e)
{
btn_Send.Enabled = false;
txt_Password.Text = "";
try
{
message = new MailMessage();
if(isValidEmail(txt_From.Text))
{
message.From = new MailAddress(txt_From.Text);
}
if (isValidEmail(txt_To.Text))
{
message.To.Add(txt_To.Text);
}
message.Body = txt_Details.Text;
//attributes for smtp
smtp = new SmtpClient("smtp.gmail.com");
smtp.Port = 587;
smtp.EnableSsl = true;
smtp.UseDefaultCredentials = false;
smtp.Credentials = new NetworkCredential("imad.majid90#gmail.com", "mypassword");
smtp.Send(message);
}
catch(Exception ex)
{
btn_Send.Enabled = true;
MessageBox.Show(ex.Message);
}
}
public bool isValidEmail(string email)
{
bool flagFalse = false; ;
if (!email.Contains('#'))
{
lbl_Error.Visible = true;
lbl_Error.ForeColor = System.Drawing.Color.Red;
lbl_Error.Text = "Email address must contain #";
return flagFalse;
}
return true;
}
}
Assuming you're using Gmail like the screenshot you posted shows, you can't check the password without trying to send the email.
My advice would be to attempt to send the email and catch an Exception if it fails. You can then show some indication that there has been an error, like a MessageBox or a Label on your form.
See the documentation for SmtpClient. The Send methods will throw an SmtpException if authentication fails.
EDIT:
Well, after seeing the additional code you posted, you are already handling any exceptions that are thrown, including an authentication failure. The user will see a MessageBox if the password is incorrect.
catch(Exception ex)
{
btn_Send.Enabled = true;
// MessageBox.Show(ex.Message);
lbl_Error.Text = "Invalid Username/Password";
}
Do a try catch for SmtpException and display the information to the user is unauthenticated.
http://msdn.microsoft.com/en-us/library/h1s04he7.aspx
It looks like your using Windows Authentication. It might be easier to fetch the user's email from Active Directory rather then prompting for credentials.
How to obtain email address with window authentication

Categories

Resources