I have a windows service that sends out emails by retriving the records from the database. The service account Windows Service is running under, is a Local admin on that machine. The issue i am having is somehow the windows service manages to send out some emails with pdf attachements that exist on the local server where windows service is located and for most of them i get an error message: Invalid Mail Attachment and having real difficulties what could be causing it? any idea on where should i start looking please?
Thanks
Try
' Initialize new mail message class
Dim objEmailMessage As New System.Net.Mail.MailMessage(EmailOutboxEntity.EmailFrom, EmailOutboxEntity.EmailTo)
' Set the email parameters
objEmailMessage.Subject = EmailOutboxEntity.EmailSubject
objEmailMessage.Body = EmailOutboxEntity.EmailBody
' Check if attachments have been specified
If Not EmailOutboxEntity.TestOriginalFieldValueForNull(EmailOutboxFieldIndex.EmailAttachements) Then
' Get an array of attachment file names to send
Dim arrAttachment As String() = Split(EmailOutboxEntity.EmailAttachements, CONST_AttachmentSeparator)
' Step through each filename and attach it to the email
For Each strAttachment As String In arrAttachment
' Attach the current file to the email
objEmailMessage.Attachments.Add(New System.Net.Mail.Attachment(strAttachment))
Next
End If
' Set the SMTP server
Dim mailServer As New System.Net.Mail.SmtpClient(pstrSMTPServer)
' Send the message
mailServer.Send(objEmailMessage)
Catch errException As Exception
' Throw an exception indicating the email failed to send
Throw New EmailOutboxManagerException(errException.Message, "Test Failed to send email, got the following error instead:")
End Try
Sorry Guys, as i have figured out the answer and it was my fault because i was running two different versions of the windows service on different servers and they were both picking up the attachments from the database and the path existed on one server where the files were saved and not on the other server and that's why some of the emails were managed to be sent.
Related
I have an issue where I'm sending a PDF file as an attachment, but when the email arrives with the client, it's arriving as a file with a name very similar to the MIME type, but with the correct content. I specify an attachment file name of "Statement.pdf", but it arrives as "application_pdf.txt" which then confuses the receiver as it doesn't open as a PDF. The mail sending is handled by a Windows Service written in Visual Basic.
Here is the main bit of code that actually sends it:
Dim SmtpServer As New SmtpClient()
Dim mail As New MailMessage()
SmtpServer.Credentials = New Net.NetworkCredential(mailAddress, mailPassword)
SmtpServer.Port = mailPort
SmtpServer.Host = mailServer
SmtpServer.EnableSsl = mailSSL
SmtpServer.DeliveryMethod = SmtpDeliveryMethod.Network
mail = New MailMessage()
If fromName <> "" Then mailName = fromName
mail.From = New MailAddress(fromAddr, mailName)
mail.IsBodyHtml = True
mail.To.Add(toAddr)
If replyTo <> "" Then
mail.ReplyToList.Add(replyTo)
End If
If cc <> "" Then
mail.CC.Add(cc)
End If
mail.Subject = subject
mail.Body = body
If attached <> "" And attachMIME <> "" And attachname <> "" Then
mail.Attachments.Add(Attachment.CreateAttachmentFromString(attached, attachMIME))
mail.Attachments.Last().ContentDisposition.FileName = attachname
End If
SmtpServer.Send(mail)
The various variables in here are passed in from the calling code and I'm confident that they're correct, in that if the password, port etc were incorrect the email wouldn't send. In particular the attachMIME is "application/pdf" which appears to be correct according to pdfa.org.
The PDF is generated on another machine, and passed to this one using FTP in binary mode. This service then reads the PDF into a string and passes it into the mail sending function:
Dim attachBytes() As Byte = Nothing
attachBytes = My.Computer.FileSystem.ReadAllBytes(FileDir & "\" & msg.attachFile)
mailAttachFile = ""
For Each attbyt As Byte In attachBytes
mailAttachFile &= Chr(attbyt)
Next
I thought I'd cracked it because I was originally using ReadAllText which strips out any non-printable characters, and I imagined that the mail transport somewhere was checking the PDF for validity, seeing the unprintable characters had changed and presuming it was some sort of mal-formed file. Unfortunately changing to ReadAllBytes didn't seem to help, and the PDF file is still arriving as a file named "attachment_pdf.txt", still with the correct content. If I save the file from my email client and then rename it, it displays perfectly as a PDF in Acrobat Reader. My customer is receiving emails from other companies with PDF attachments, so it's not just that his email provider doesn't trust PDFs.
I don't simply use AddAttachment(filename) to load the attachment because the code works in two ways - one where the service downloads the email files from a remote FTP server, and the other (this one) where the files are sent to the machine running the service and the service opens them locally. In order to keep the actual mail sending the same, loading the files is done further "up" the code and the resulting email message and attachment passed in here via a function call. So by the time I get to the first code block I posted above, the code doesn't know (or care) where the message and attachment came from.
Is there anything glaringly obvious in what I have posted that might be causing this issue? I should add that I have the same code running on another machine, using gmail as the mail transport (which this one does not) and the other method I mentioned above and it sends a PDF attachment every day without issue.
(Edited to clarify that the attachment file contents are not changing, just the attachment name is changing, which confuses the receiver.)
When trying to send an email using a Visual Basic Console App I get an error: "The operation timed out". I'm sending from a Windows 7 pc. Can this be done?
I've found many posts that say it fails because there is no SMTP client on Windows 7. However, I downloaded smpt4dev and get the same results when I try to connect to that via "localhost".
But I can telnet to the server from the same pc and get no errors. I can also send an email using these telnet commands:
telnet SMTP.domain.xyz 25
helo SMTP.domain.xyz
mail from: f#domain.com
rcpt to: t#domain.com
data
subject: test email
.
quit
I have tried this with a few different smtp servers and I get the same results. I know that my server name, port, username and pw are correct.
Imports System.Net.Mail
Try
Dim SMTPClientObj As New Net.Mail.SmtpClient
SMTPClientObj.UseDefaultCredentials = False
SMTPClientObj.Credentials = New System.Net.NetworkCredential(username, password)
SMTPClientObj.Host = "mysmtpserver"
SMTPClientObj.Port = 25
SMTPClientObj.EnableSsl = False
Dim e_mail As New MailMessage()
e_mail.From = New MailAddress("test#test.com")
e_mail.To.Add("test2#test.com")
e_mail.Subject = "Email Sending Test"
e_mail.IsBodyHtml = False
e_mail.Body = "Test email from VB"
SMTPClientObj.Send(e_mail)
Dim x As New Mail.SmtpStatusCode
Console.WriteLine("SmtpStatusCode: " & CStr(x))
Console.WriteLine("Mail Sent.")
Catch ex As Exception
Dim x As New Mail.SmtpStatusCode
Console.WriteLine("SmtpStatusCode: " & CStr(x))
MsgBox(ex.Message)
MsgBox(ex.ToString)
MsgBox(ex.InnerException)
End Try
At this point I'd just like to be able to get more details on the error instead of the simple timed out message. But I've never used the SmtpStatusCode before and am not sure how to use it.
The ex.InnerException prompt is always blank.
Can you give me any pointers on how to get more detailed error info? Or what I need to do to get this to work on my windows 7 pc?
Thank you
Turns out Digital Guardian was blocking port 25. McAfee wasn't the problem nor was Group policy.
Thanks to everyone for their assistance.
I currently have two Lotus Notes databases, each with their own email addresses associated with them. As expected, when I send an email through the first database to my gmail account, it shows up as "From: notesAccount1#db1.com" and when I send using the second database, the message shows up as "From: notesAccount2#db2.com" in my gmail.
I have working code that opens up the second database, searches the inbox for an email containing a certain keyword, and extracts an email address from that email. It then creates a new document in that second database, inserts the recipients name, subject, body, etc., sends the email, and saves it to my sent folder. Everything works smoothly up to this point.
However, when I send an email from the second database to my gmail account using this VBA method, the email shows up in my gmail as "From: notesAccount1#db1.com" - the email associated with the first database.
I can't figure out why this is happening. Pretty limited knowledge of the interactions between VBA and Lotus Notes, and Lotus Notes servers/databases in general. The first database is technically my default one that only I have access to and the second database was added later and multiple people have access to it. I don't know if that's relevant.
Would appreciate any help! Thanks.
Note: This code was copied and adapted from several sources, including some on SO, IBM and other Notes sources, and anything else Google threw my way, including
http://www.fabalou.com/vbandvba/lotusnotesmail.asp
http://www-01.ibm.com/support/docview.wss?uid=swg21178583
Code: (This will have to be adapted as I have taken out server names and mail file names)
Sub ReadNotesEmail()
Dim sess As Object
Dim db As Object
Dim folder As Object
Dim docNext As Object
Dim memoSenders As Variant
Dim newEmail As Object
Dim view As Object
Dim entry As Object
Dim entries As Object
Dim templateEmail As Object
Dim mailServer As String
Dim mailFile As String
Dim folderName As String
Dim todayDate As String
Dim memoBody As String
Dim senderEmail As String
Dim emailStartPos As Integer
Dim emailEndPos As Integer
'This program will search a particular folder in a Notes database that I designate.
'It will search that folder for emails that contain certain key words. Once it finds
'an email that fits, it will grab the sender's email address (written in the body, not
'in the 'from') and send them an email.
'Name of folder to search for emails
folderName = "($Inbox)"
'Create a Lotus Notes session and open it (will require password)
Set sess = CreateObject("Lotus.NotesSession")
sess.Initialize ("")
'Set the mail server, mail file, and database. This will be the tricky part as I need this to
'look at the second mail server as opposed to the default mail server of jdyagoda
Set db = sess.GETDATABASE("***name of second Notes server***", "***name of second mail file***")
'Open the mail database in notes
If Not db.IsOpen = True Then
Call db.Open
End If
Set folder = db.GetView(folderName)
'Now look through the emails one at a time with a loop that ends when no emails are left.
'If an email contains the key word, look for the email address of the person who submitted
'the contact-us form. It follows the string "Email:" and preceeds
'the string "Phone:".
Set doc = folder.GetFirstDocument
Do Until doc Is Nothing
Set docNext = folder.GETNEXTDOCUMENT(doc)
memoBody = LCase(doc.GetItemValue("body")(0))
If (memoBody Like "*") Then 'This is where you designate the keyword
'Here's where you extract the email address - taken out for the purpose of this SO question
'senderEmail = testName#test.com
'Now create a new email to the intended recipient
Set newEmail = db.CREATEDOCUMENT
Call newEmail.ReplaceItemValue("Form", "Memo")
Call newEmail.ReplaceItemValue("SendTo", senderEmail)
Call newEmail.ReplaceItemValue("Subject", "Thank you for your email")
Call newEmail.ReplaceItemValue("body", "Test Body 1. This is a test.")
newEmail.SAVEMESSAGEONSEND = True
'Send the new email
Call newEmail.ReplaceItemValue("PostedDate", Now()) 'Gets the mail to appeaer in the sent items folder
Call newEmail.SEND(False)
End If
Set doc = docNext
Loop
End Sub
Notes will normally send the mail using the email address for the ID you use to login. So if you login using notesAccount1/Domain, then all emails will be coming from notesAccount1#example.com.
If you want to fake the sender, you need to use an undocumented method: inject the email directly into mail.box.
You should not attempt to do this unless you really know what you are doing.
I have posted code on my blog for a mail notification class, it supports this work-around to set the sender on outgoing emails. You can find the latest code at http://blog.texasswede.com/updated-mailnotification-class-now-with-html-email-support-and-web-links/
I am running Windows Server 2008 R2. I installed the fax server role on the server. I am able to fax documents using the external fax modem attached to the server from computers attached to the network by printing the documents and selecting "Fax on MYSERVER". I am able to fax a .pdf using the following code (which I got from mdsn.microsoft.com) from the server but not from any other computer even when logged into the computer using the administrator account.
Sub fax_report(location_fax_number, report_name, fax_location, fax_file_path)
Dim objFaxDocument As New FAXCOMEXLib.FaxDocument
Dim objFaxServer As New FAXCOMEXLib.FaxServer
Dim JobID As Object
On Error GoTo Err_Clear
Err_Clear:
If Err <> 0 Then
Err.Clear
Resume Next
End If
'Connect to the fax server
objFaxServer.Connect ("\\MYSERVER")
'Set the fax body
objFaxDocument.Body = fax_file_path
'Name the document
objFaxDocument.DocumentName = report_name
objFaxDocument.Recipients.add (location_fax_number)
JobID = objFaxDocument.ConnectedSubmit(objFaxServer)
objFaxServer.Disconnect
End Sub
The error I'm getting is:
Description: "Operation failed"
HelpContext: 1000440
HelpFile: "C:\Program Files (x86)\Common Files\Microsoft
Shared\VBA\VBA7.1\1033\VbLR6.chm"
LastDllError: 0
Number: -2147023741
Source: "FaxComEx.FaxDocument.1"
Although I am able to fax a .pdf from the server when I try from a computer on the network it fails. I am able to send a .txt file fro a computer on the network. It looks like the .pdf isn't automatically being converted to a .tiff file like it is when I run the code on the server. When I run the code from the server Adobe Acrobat Reader DC opens, the .pdf is opened and converted then faxed without error. Adobe stays open and I can see a temp file was created, it isn't available to be opened from the recent file lists menu.
I figured out the solution. I needed to set Adobe Acrobat Reader DC as the default program to handle .pdfs on the remote computers.
I'm in the process of writing some code to download and process the attachments of email messages and then process them. The code is working as required in some cases, but still has some major problems.
Whenever the code loads the attachment into a file on the local disk, it takes a very long time to do so and often times out with the following exception as a result of the slow download:
A first chance exception of type 'Microsoft.Exchange.WebServices.Data.ServiceRequestException' occurred in Microsoft.Exchange.WebServices.dll
I may be wrong, but if the exchange server in question is on the same gigabit network as the server running the code and outlook has fast access to emails, attachments, etc then attachments should download considerably faster than they do and much more consistently. Here are some example of download/load times:
800KB Zip - 1m 4s
840KB Zip - 6m 18s
1.33MB Zip - 11m 23s
2.78MB Zip - 17m 3s
I have tried setting the EWS connection timeout setting to 300000ms instead of the default 100000ms to give the attachments more time to download and the number of exceptions has decreased slightly but the waiting time is now way too long.
The code does run in threads, no more than 8 at a time (10 being the throttling limit for EWS i believe), but i cant imagine that would make much of a difference. (It hasn't done when I've been testing single emails at a time).
Here is the threaded code that downloads the attachments (some un-related bits removed for simplicity):
Dim strMessageFolder As String
' Prepare the directory where this emails attachments will be stored
strMessageFolder = g_strFolder_Temp & strMessageID & "\"
' Create a folder to store the attachments for this email
Call FileSystem_CreateFolder(strMessageFolder, True)
' Process the emails attachments
For Each emailAttachment In emailMessage.Attachments
Dim fileattach As FileAttachment
'Dim fileattachStream As FileStream
Dim strAttachmentFile As String
' Prepare for the downloading of the attachment
fileattach = emailAttachment
blnTryFailed = False
intAttempts = 0
strAttachmentFile = strMessageFolder & fileattach.Name
' Handle up to 3 download attempts
Do
Try
' Try to download the attachment - Method 1
fileattach.Load(strAttachmentFile)
' Try to download the attachment - Method 2
'fileattachStream = New FileStream(strAttachmentFile, FileMode.OpenOrCreate, FileAccess.ReadWrite)
'fileattach.Load(fileattachStream)
'fileattachStream.Close()
'fileattachStream.Dispose()
blnTryFailed = False
Catch ex As Exception
blnTryFailed = True
' Ensure the failed download is deleted
Call FileSystem_DeleteFile(strAttachmentFile)
intAttempts += 1
End Try
Loop While blnTryFailed And intAttempts < 3
' If the attachment download was unsuccessful then we cannot process the current email
If blnTryFailed = True Then
emailMessage.IsRead = False
'message.Subject = message.Subject & " - Attachment download failed, skipped"
Try
emailMessage.Update(ConflictResolutionMode.AutoResolve)
Catch ex As Exception
Call Logging_Add("Unable to mark email as skipped", strMessageID, "Debug")
End Try
Exit Sub
End If
As mentioned previously, im aware of the Exchange throttling but cannot find anything related to the speed at which attachments are downloaded.
So my question is what could possibly be causing such slow download speeds?
I have the same issue with my app. The problem was caused by default EWS setting which writes to Console all HttpRequest and HttpResponse messages between EWS and application. Turning off TraceFlags was blessing.
My code in c#:
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
service.TraceFlags = TraceFlags.None;