outlook vsto sending mail - outlook

I've been struggling with this for a while now and I can't get an answer anywhere.
I made an outlook add in which has a ribbon and two buttons, The one button opens up a mailitem where you can compose your mail and then the 2nd button sends the mail.
In the background it takes all of the recipients and adds it to the bcc field and sends the mail in batches for instance if there are 100 recipients it will send to 25 people at time.
So my problem is that it works perfectly on the developer PC but the send button doesn't work on the end user PC. The add in loads registries are fine and it targets the right .Net framework everything!
private void CreateEmailItem(Outlook.Recipient strRecipientAddressTo)
{
string strFilePath = #"c:\temp\OutlookAttachments";
string[] strFiles = Directory.GetFiles(strFilePath);
bool bFileExists = Directory.Exists(strFilePath);
Outlook.MailItem eMail = (Outlook.MailItem)
Globals.ThisAddIn.Application.CreateItem(Outlook.OlItemType.olMailItem);
Outlook.MailItem mailItem = Globals.ThisAddIn.Application.ActiveInspector().CurrentItem as Outlook.MailItem;
eMail.Subject = mailItem.Subject;
eMail.BCC = mailItem.To;
eMail.Body = mailItem.Body;
if (bFileExists)
{
foreach (string file in strFiles)
{
File.SetAttributes(file, FileAttributes.Normal);
eMail.Attachments.Add(file);
}
}
((Outlook._MailItem)eMail).Send();
}
When the send button on the ribbon is clicked this method is called, but on end user the button just doensn't fire .. can this be permissions ? or any advice would be very much appreciated !!!!

It is hard to suggest there but did you add any logging there. There can be chances that you are getting some crash in following line..
email.Attachments.Add(file)
And thats why it is not reaching until send statement. You can check the event logs on user's system as well. They might help you.

Related

Stuck for over 2 months getting an outlook addin to work

This is basically a re-post of a previous question, but I've spent over 2 months stuck on this same issue and I haven't made any progress of any kind. Long story short, sometimes it fires and sometimes it doesn't. Sometimes it loads once, sometimes Outlook defaults it to "inactive" and there's nothing I seem to be able to do about it. When it DOES fire, it hangs up when trying to send the first email. So, I have old appointments outside of the date range I'm checking and the messagebox appears for those. When it gets to "new" appointments (within the date range), sometimes it pops up the first messagebox but hangs up trying to send the email. SOmetimes that first "good" messagebox fails to pop up. The last advice I got regarding this issue was to build a log file, but I couldn't figure out how/what good it was going to do me or honestly I wasn't even sure what I was going to need to log, and the gentleman who suggested it never responded to me when I asked. Thank you in advance for your help, this is easily one of the most frustrating things I've ever run in to as a developer.
using System;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
using Microsoft.Office.Interop.Outlook;
using System.Windows.Forms;
namespace OutlookAddIn1
{
public partial class ThisAddIn
{
//Outlook.Inspectors inspectors;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
doStuff();
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
}
#region VSTO generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InternalStartup()
{
this.Startup += new System.EventHandler(ThisAddIn_Startup);
this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
}
//https://msdn.microsoft.com/en-us/library/ms268866.aspx
private void doStuff()
{
Outlook.Application app = new Outlook.Application();
Thread.Sleep(30000); //120 seconds - was 120000
DateTime firstRun = DateTime.Now; //So we can check every 24 hours? Maybe once initially as well.
DateTime lastRun = DateTime.Now;//.AddHours(1); //We're going to compare this to firstRun
bool whileTrue = true;
//int test = 0;
try
{
while (whileTrue)
{
if (whileTrue == true)//(firstRun > lastRun.AddDays(1))
{
Outlook.MAPIFolder calendarFolder = Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
Outlook.Items outlookCalendarItems = calendarFolder.Items;
outlookCalendarItems.IncludeRecurrences = true; //was true
List<Outlook.AppointmentItem> lst = new List<Outlook.AppointmentItem>();
foreach (Outlook.AppointmentItem item in outlookCalendarItems)
{
lst.Add(item);
//We can probably just handle logic in here without the second for loop that comes next
}
foreach (Outlook.AppointmentItem x in lst)
{
DateTime startDate = DateTime.Now.AddDays(1);
DateTime endDate = DateTime.Now.AddDays(5);
DateTime apptDate = x.Start;
if (x.Subject.ToLower().Contains("telos"))
{
MessageBox.Show("X: " + x.Start + "XYZ: " + x.Subject);
if (x.Start > startDate && x.Start < endDate)
{
Microsoft.Office.Interop.Outlook.MailItem email = app.CreateItem((OlItemType.olMailItem));
//Outlook.MailItem mail = (Outlook.MailItem)Globals.ThisAddIn.Application.CreateItem(Outlook.OlItemType.olMailItem);
//Outlook.Recipient recipient = Globals.ThisAddIn.Application.Session.CreateRecipient("cindy#soundstewardship.com");
//email.Sender = recipient.AddressEntry;
//Outlook.Recipient recipient = app.Session.CreateRecipient("someone#example.com");
//email.Sender = recipient.AddressEntry;
//email.SentOnBehalfOfName = "someone#example.com";
email.Display(true); //was false
email.Subject = "You have a new appointment";
email.Importance = Outlook.OlImportance.olImportanceLow;
email.To = Application.Session.CurrentUser.AddressEntry.Address; //Current email address.
email.Body = "This email was automatically generated to remind you have an upcoming appointment on: " + x.Start.ToString();
email.Save();
email.Close(OlInspectorClose.olSave);
//((Outlook._MailItem)email).Send();
//email.Send();
//((Outlook._MailItem)mailItem).Send();
}
}
}
lastRun = DateTime.Now;
whileTrue = false;
}
else
{
/*
Outlook.MailItem email = new Outlook.MailItem();
email.Subject = "This is only a test.";
email.To = Application.Session.CurrentUser.AddressEntry.Address; //Current email address.
email.Body = "This is only a test.";
//email.Send();
((Outlook._MailItem)email).Send();
* */
}
}
}
catch (System.Exception e) //Microsoft.Office.Interop.Outlook.Exception e
{
MessageBox.Show(e.InnerException.ToString());
}
finally
{
app.Quit();
}
}
#endregion
}
}
First of all, there is no need to create a new Outlook Application instance in the code. You need to use the Application property of the add-in class.
At startup, I need it to read all appointments whose subject contains a certain string
Don't use the foreach for iterating over all items in the folder. Instead, you need to use the Find/FindNext or Restrict methods of the Items class. You may read more about these methods in the following articles (the sample code is included):
How To: Retrieve Outlook calendar items using Find and FindNext methods
How To: Use Restrict method in Outlook to get calendar items
When you are done I'd recommend using the Resolve or ResolveAll methods of the Recipient(s) class to resolve all recipients against the address book.
Also, like 75% of the time this addin loads directly as "inactive" and doesn't fire.
Microsoft Office applications can disable add-ins that behave unexpectedly. If an application does not load your add-in, the application might have hard disabled or soft disabled your add-in.
Hard disabling can occur when an add-in causes the application to close unexpectedly. It might also occur on your development computer if you stop the debugger while the Startup event handler in your add-in is executing.
Soft disabling can occur when an add-in produces an error that does not cause the application to unexpectedly close. For example, an application might soft disable an add-in if it throws an unhandled exception while the Startup event handler is executing.When you re-enable a soft-disabled add-in, the application immediately attempts to load the add-in. If the problem that initially caused the application to soft disable the add-in has not been fixed, the application will soft disable the add-in again. Read more about that in the How to: Re-enable an Add-in That Has Been Disabled article.
Also Outlook 2013 monitors add-in performance metrics such as add-in startup, shutdown, folder switch, item open, and invoke frequency. Outlook records the elapsed time in milliseconds for each performance monitoring metric. For example, the startup metric measures the time required by each connected add-in during Outlook startup. Outlook then computes the median startup time over 5 successive iterations. If the median startup time exceeds 1000 milliseconds (1 second), then Outlook disables the add-in and displays a notification to the user that an add-in has been disabled. The user has the option of always enabling the add-in, in which case Outlook will not disable the add-in even if the add-in exceeds the 1000 millisecond performance threshold. See Performance criteria for keeping add-ins enabled for more information.
Why would you sleep on the main Outlook thread? And then loop through all items in the folder instead of using Items.Restrict or Items.Find/FindNext?

Issue with SentOnBehalfOfName

i'm stack with Outlook issue where i want to change Email Sender. I want to send all emails from Outlook with one sender. When i change sender from Outlook it works fine but when i change it from Outlook plugin it's not work. I'm using following code:
private void adxOutlookEvents_ItemSend(object sender, ADXOlItemSendEventArgs e)
{
if (e.Item is MailItem)
{
MailItem mail = e.Item as MailItem;
mail.SentOnBehalfOfName = "UserName";
mail.Save();
return;
}
}
But nothing happens. I don't see any error or exception but email come to Outlook with old sender. Can you please help me with that?
UPDATED: The way how i fix it. We cant use property "SentOnBehalfOfName" Outlook handle it incorect. Except it you should use "Sender" property:
mail.Recipients.Add(mail.SentOnBehalfOfName);
mail.Recipients.ResolveAll();
var adressEntry = mail.Recipients[mail.Recipients.Count].AddressEntry;
mail.Recipients.Remove(mail.Recipients.Count);
mail.Sender = adressEntry;
Are you sending through Exchange and want to send on behalf of another user (do you have the permission?) or trying to send through a particular POP3/SMTP account (use MailItem.SendUsingAccount property)?

Send a mail from outlook by getting To list from SQl server

I am stuck with a issue from 5 days.
I need a way to attain following requirement.
mailing list is present in Database(SQL server)
I have a mail in Outlook
now i have to send mail to all the 200,000 mail ids in Database
**Note one mail can have only 200 mail IDs so
200,000/200=1000 mails **Note: this 200,000 count is not fixed it will decrease and increase>
like jhon#xyz.com will be present today , next day we may need not send to him
his name might be completely removed (so DL is not an option)
I need a way to automate this
All i have a sleep less nights and coffee cups on my desk
I work in ASP.net any PL which meets this need is fine.
I assume that you know how to create sql statement for what you need and how to retrieve data from database in .NET. This means that only issue is actually sending this from outlook.
Here is an article that describes this in detail and piece of code copied from there.
using System;
using System.Text;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace OutlookAddIn1
{
class Sample
{
public static void SendEmailFromAccount(Outlook.Application application, string subject, string body, string to, string smtpAddress)
{
// Create a new MailItem and set the To, Subject, and Body properties.
Outlook.MailItem newMail = (Outlook.MailItem)application.CreateItem(Outlook.OlItemType.olMailItem);
newMail.To = to;
newMail.Subject = subject;
newMail.Body = body;
// Retrieve the account that has the specific SMTP address.
Outlook.Account account = GetAccountForEmailAddress(application, smtpAddress);
// Use this account to send the e-mail.
newMail.SendUsingAccount = account;
newMail.Send();
}
public static Outlook.Account GetAccountForEmailAddress(Outlook.Application application, string smtpAddress)
{
// Loop over the Accounts collection of the current Outlook session.
Outlook.Accounts accounts = application.Session.Accounts;
foreach (Outlook.Account account in accounts)
{
// When the e-mail address matches, return the account.
if (account.SmtpAddress == smtpAddress)
{
return account;
}
}
throw new System.Exception(string.Format("No Account with SmtpAddress: {0} exists!", smtpAddress));
}
}
}
What I would suggest is to skip using outlook unless that’s really necessary and send email by directly communicating with SMTP server.
Just search for “how to send email from C#” or something similar and you’ll find a ton of examples.

Umbraco - how to add a custom notification?

I'm using Umbraco 4.6.2, and need to extend the default notifications it provides. For the sake of this question, let's say I am trying to add an "Unpublish" notification.
In \umbraco\presentation\umbraco\dialogs\notifications.aspx.cs it constructs the list of checkbx items shown to the user when opening the "Notifications" dialogue from the context menu.
I see that each Action has a ShowInNotifier property - how can I set this value to true for the UnPublish action?
Does this require modifying the core codebase, or is there a nice way I can gracefully extend Umbraco?
So after I have added this, users can subscribe to the UnPublish notification (am I missing any steps here?).
Will this automagically send notifications now?
I'm guessing not, so the next thing I have done is hooked the UnPublish event:
public class CustomEvents : ApplicationBase
{
public CustomEvents()
{
Document.AfterUnPublish += new Document.UnPublishEventHandler(Document_AfterUnPublish);
}
void Document_AfterUnPublish(Document sender, umbraco.cms.businesslogic.UnPublishEventArgs e)
{
var user = User.GetCurrent();
if (!string.IsNullOrEmpty(user.Email) && user.GetNotifications(sender.Path).Contains("UnPublish"))
{
//Send a notification here using default Umbraco settings, or, construct email and send manually:
string umbracoNotificationSenderAddress = ""; //How to get the address stored in umbracoSettings.config -> <notifications> -> <email>
//How to use the same subject/message formats used for other notifications? With the links back to the content?
string subject = "Notification of UnPublish performed on " + MyUtilities.GetFriendlyName(sender.Id);
string message = MyUtilities.GetFriendlyName(sender.Id) + " has just been unpublished.";
umbraco.library.SendMail(umbracoNotificationSenderAddress, user.Email, subject, message, true);
}
}
}
So the bits of that code that are not real/I need some pointers on:
Is that the correct way for checking if a user is subscribed to a particular notification?
How can I send a notification using the default umbraco settings? (e.g. generate an email just like the other notifications)
If that is not possible and I must construct my own email:
How do I get the from email address stored in umbracoSettings.config that
How can I copy the formatting used by the default Umbraco notifications? Should I manually copy it or is there a nicer way to do this (programmatically).
Any help (or even just links to relevant examples) are appreciated :>
My colleague got this working.
Create a class that overrides the action you wish to have notifications for.
You can see all the actions in /umbraco/cms/Actions
public class ActionUnPublishOverride : umbraco.BusinessLogic.Actions.ActionUnPublish, IAction
{
... see what the other actions look like to find out what to put in here!
In the overridden class, you will have a public char Letter. Set this to match the event to hook into. You can find the letters each event has in the database.
Set the public bool ShowInNotifier to true.
That's it!
I've got this working on Umbraco 4.7 by using the UmbracoSettings class:
http://www.java2s.com/Open-Source/CSharp/Content-Management-Systems-CMS/umbraco/umbraco/businesslogic/UmbracoSettings.cs.htm
umbraco.library.SendMail(umbraco.UmbracoSettings.NotificationEmailSender, newMember.Email, "email subject", "email body", false);

Using Redemption to reply to a mail only intermittently sets the body text

I'm using the below method to reply to mails coming in to a business function mailbox.
The body text being added is only intermittently being set. This method is only called when someone has emailed in to unsubscribe from a mailing but the email address of the sender (or in the body) hasn't been found in the database and we want to ask them to send us the mail address they want to unsubscribe.
private void replyToMail(OutlookItem item)
{
RDOSession session = new RDOSession();
session.Logon(null, null, null, true, null, null);
RDOMail thisItem = session.GetMessageFromID(item.EntryID, item.StoreID, null);
RDOMail reply = thisItem.Reply();
RDOAddressEntry optingout = session.AddressBook.GAL.ResolveName("optingout");
//reply.Sender = optingout; this had no effect
reply.SentOnBehalfOf = optingout;
reply.Subject = "Automated Response - Could not complete unsubscribe";
reply.Body = "This is an automated response from the Newsletter unsubscribe system. We couldn't find "+item.Sender+" in our database to unsubscribe you from our mailings.\r\n\r\nPlease reply to this mail and include the email address you want to unsubscribe.\r\n\r\nKind Regards\r\n.";
reply.Send();
session.Logoff();
}
Firstly, if you are already usign OOM, there is no reason to call RDOSession.Logon. You can simply ste the MAPIOBJECT property:
Replace the line session.Logon() with
session.MAPIOBJECT = item.Application.Session.MAPIOBJECT
do not call Logoff.
Secondly, do yo umean the message is received with out a body? Do you see teh empty bofy in the Sent Items folder?
I had to edit thingie.HTMLBody as well as thingie.Body.
I suppose I could have figured out how to tell when to set the value of each one but since I just want to be sure that I have control of the body in this instance I'm simply setting both.

Resources