VSTO 从 Outlook 中的自定义表单按钮发送电子邮件
VSTO send email from custom Form button in Outlook
我的目标,用户想发送一封新邮件,填写完(.TO
、.CC
、.Body
等)点击发送按钮会显示一个客户Form
发送选项所在的位置。一种选择是在用户创建电子邮件时发送电子邮件(正常 send
按钮功能)。
是否知道如何将 ItemSend
功能分配给自定义表单中的按钮?
ThisAddIn.cs
-> 打开自定义表单
public partial class ThisAddIn
{
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);
}
Application_ItemSend
private void Application_ItemSend(object Item, ref bool Cancel)
{
if (Item is Outlook.MailItem)
{
Form1 f = new Form1();
f.Show();
}
Cancel = true;
}
ChooseFormSend.cs
-> 自定义发送按钮,
public void btn_standard_Click(object sender, System.EventArgs e)
{
//mail.Send() -> send email which user whant to send
}
更新(所有答案聚集在一起,使这项工作有效)
ThisAddIn.cs
public partial class ThisAddIn
{
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);
private bool ProcessEmail(Outlook.MailItem mailItem, MailSendType SendType)
{
switch (SendType)
{
case MailSendType.Normal:
return false;
case MailSendType.WithAdverts:
//mailItem.BCC += "ad@server.xyz";
mailItem.HTMLBody += @"<b>Some bold text at the end :)</b>";
mailItem.HTMLBody += @"1233";
return false; // send the mail
case MailSendType.WithCoupon:
mailItem.CC += "coupon@server.xyz";
mailItem.HTMLBody += @"";
return false; // send the mail
// by default don't send the mail
default:
return true;
}
}
private void Application_ItemSend(object Item, ref bool Cancel)
{
if (Item is MailItem) // ensures Item is a mail item
{
using (Form1 form_ChooseForm = new Form1())
{
DialogResult dr = form_ChooseForm.ShowDialog();
if (dr == DialogResult.OK) // shows the form as a dialog
{
Cancel = ProcessEmail((MailItem)Item, form_ChooseForm.SendType);
// MessageBox.Show("The OK button on the form was clicked.");
}
else
{
// MessageBox.Show("Cancel process");
Cancel = true;
}
}
}
}
}
ChooseFormSend.cs
using Microsoft.Office.Core;
using Microsoft.Office.Interop.Outlook;
using Microsoft.Office.Tools.Outlook;
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 System.Net;
using System.Net.Mail;
using System.Runtime.InteropServices;
namespace OutlookControll
{
public enum MailSendType
{
NoSend,
Normal,
WithAdverts,
WithCoupon
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public MailSendType SendType = MailSendType.NoSend;
private void Btn_ShowSecondForm_Click(object sender, EventArgs e)
{
AddItemsForm f2 = new AddItemsForm();
f2.ShowDialog();
this.Hide();
}
private void Btn_cancel_Click(object sender, EventArgs e)
{
Button Btn_cancel_Click = new Button();
Btn_cancel_Click.DialogResult = DialogResult.Cancel;
this.Hide();
}
public void Btn_standard_Click(object sender, EventArgs e)
{
Button Btn_standard_Click = new Button();
Btn_standard_Click.DialogResult = DialogResult.OK;
Controls.Add(Btn_standard_Click);
SendType = MailSendType.Normal;
this.Hide();
}
}
Btn_standard_Click.DialogResult = DialogResult.OK
可以设置在Properties
-> Behavior
-> DialogResult
-> OK, Cancel, Abort等
我可以考虑 3 种可能的情况:
- 按发送 > 弹出表单 > Select 表单上的选项 > 修改电子邮件内容 > 发送电子邮件
- 按发送 > 弹出表单 > 表单上的 Select 选项 > 创建并发送新电子邮件(发送 1 封或多封新电子邮件)(丢弃旧电子邮件) >发送电子邮件
- 按发送 > 弹出表单 > 表单上的 Select 选项 > 创建并发送新电子邮件(发送 1 封或多封新电子邮件)(发送旧电子邮件) >发送电子邮件
请注意,一旦修改邮件内容就意味着修改所有内容。更改发件人更改主题等。因此,如果您想创建一封新电子邮件并丢弃旧电子邮件,选项 1 仍然可以完全操纵原始电子邮件。
允许用户select相关选项的对话框。
注意:放置表单按钮时,请确保在属性检查器的行为下设置 DialogResult
选项。这允许在单击自动关闭并从对话框返回的按钮之一后返回 DialogResult:OK
。
public enum MailSendType
{
NoSend,
Normal,
WithAdverts,
WithCoupon
}
public partial class SendItemForm : Form
{
public SendItemForm()
{
InitializeComponent();
}
public MailSendType SendType = MailSendType.NoSend;
private void button1_Click(object sender, EventArgs e)
{
SendType = MailSendType.Normal;
}
private void button2_Click(object sender, EventArgs e)
{
SendType = MailSendType.WithAdverts;
}
}
选项 1:仅修改电子邮件的内容
注意显示 f.ShowDialog()
而不是 f.Show()
这会阻止当前线程继续发送操作并等待用户 select 表单上的按钮。对话框中的 f.SendType
已设置并用于指示用户 select 编辑了哪个选项。使用 ProcessEmail
可以操纵电子邮件,并且 return false
会导致在 false
向下传播到父函数 Cancel = false
时发送被操纵的电子邮件(不要取消发送)。
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
// create a global event listener for sending items
Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);
}
// this function is used to modify the mail object before sending it (More variables could be added to extend the functionality)
private bool ProcessEmail(Outlook.MailItem mailItem, MailSendType sendType)
{
switch (sendType)
{
case MailSendType.Normal:
return false; // send the mail as is don't mainpulate the mailItem variable
case MailSendType.WithAdverts:
mailItem.BCC += "ad@server.xyz";
mailItem.HTMLBody += @"<b>Some bold text at the end :)</b>";
mailItem.HTMLBody += @"</img src='https://server.xyz/ad1.png'>";
return false; // send the mail
case MailSendType.WithCoupon:
mailItem.CC += "coupon@server.xyz";
mailItem.HTMLBody += @"</img src='https://server.xyz/coupon1.png'>";
return false; // send the mail
// by default don't send the mail
default:
return true;
}
}
private void Application_ItemSend(object Item, ref bool Cancel)
{
if (Item is Outlook.MailItem) // ensures Item is a mail item
{
using (SendItemForm f = new SendItemForm()) // creates the form
if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK) // shows the form as a dialog
//if statement ensures the process will only proceed if an OK is returned
//(The form has a cancel button or it could crash or anything else)
Cancel = ProcessEmail((Outlook.MailItem)Item, f.SendType); // process the email with the SendType
}
}
选项 2/3 发送新电子邮件
此方法重点介绍了如何在 Outlook 中发送新电子邮件。注意:已测试使用 MailItem.Send()
发送电子邮件并且它不会再次调用 Application_ItemSend
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);
}
private void SendNewEmail(string to, string greeting, MailSendType sendType)
{
Outlook.MailItem newMailItem = Application.CreateItem(Outlook.OlItemType.olMailItem);
newMailItem.To = to;
newMailItem.SendUsingAccount = Application.Session.Accounts[1]; // Optional can leave blank to send from default account (Array starts at 1)
newMailItem.Subject = "New Mail";
newMailItem.Body = $"{greeting} {newMailItem.To}\nExample Body from {sendType.ToString()}";
// Part of Original answer but it's not relevant. However I will leave it in the event that it is of use to someone
//((Outlook.ItemEvents_10_Event)newMailItem).Send += (ref bool Cancel) => { /*do nothing*/ };
newMailItem.Send(); // send the mail
}
private void Application_ItemSend(object Item, ref bool Cancel)
{
if (Item is Outlook.MailItem) // ensures Item is a mail item
{
using (SendItemForm f = new SendItemForm()) // creates the form
if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK) // shows the form as a dialog
{
//if statement ensures the process will only proceed if an OK is returned
//(The form has a cancel button or it could crash or anything else)
// send 3 mails
SendNewEmail("admin1@server.xyz", "Hi", f.SendType);
SendNewEmail("admin2@server.xyz", "Hello", MailSendType.Normal);
SendNewEmail("admin3@server.xyz", "Yo", f.SendType);
// either send or don't send the orginal one
// by default Cancel is set to false (So by default the message will send)
// send the 3 mails and send the original one typed up by the user
//Cancel = false;
// send the 3 mails and do not send the original one currently typed up by the user
// Cancel = true;
}
}
}
在这 2 个示例和 f.ShowDialog()
设置之间,您应该能够找到您寻求的解决方案。您还可以通过修改原始电子邮件并发送额外的电子邮件来混合搭配。
我的目标,用户想发送一封新邮件,填写完(.TO
、.CC
、.Body
等)点击发送按钮会显示一个客户Form
发送选项所在的位置。一种选择是在用户创建电子邮件时发送电子邮件(正常 send
按钮功能)。
是否知道如何将 ItemSend
功能分配给自定义表单中的按钮?
ThisAddIn.cs
-> 打开自定义表单
public partial class ThisAddIn
{
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);
}
Application_ItemSend
private void Application_ItemSend(object Item, ref bool Cancel)
{
if (Item is Outlook.MailItem)
{
Form1 f = new Form1();
f.Show();
}
Cancel = true;
}
ChooseFormSend.cs
-> 自定义发送按钮,
public void btn_standard_Click(object sender, System.EventArgs e)
{
//mail.Send() -> send email which user whant to send
}
更新(所有答案聚集在一起,使这项工作有效)
ThisAddIn.cs
public partial class ThisAddIn
{
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);
private bool ProcessEmail(Outlook.MailItem mailItem, MailSendType SendType)
{
switch (SendType)
{
case MailSendType.Normal:
return false;
case MailSendType.WithAdverts:
//mailItem.BCC += "ad@server.xyz";
mailItem.HTMLBody += @"<b>Some bold text at the end :)</b>";
mailItem.HTMLBody += @"1233";
return false; // send the mail
case MailSendType.WithCoupon:
mailItem.CC += "coupon@server.xyz";
mailItem.HTMLBody += @"";
return false; // send the mail
// by default don't send the mail
default:
return true;
}
}
private void Application_ItemSend(object Item, ref bool Cancel)
{
if (Item is MailItem) // ensures Item is a mail item
{
using (Form1 form_ChooseForm = new Form1())
{
DialogResult dr = form_ChooseForm.ShowDialog();
if (dr == DialogResult.OK) // shows the form as a dialog
{
Cancel = ProcessEmail((MailItem)Item, form_ChooseForm.SendType);
// MessageBox.Show("The OK button on the form was clicked.");
}
else
{
// MessageBox.Show("Cancel process");
Cancel = true;
}
}
}
}
}
ChooseFormSend.cs
using Microsoft.Office.Core;
using Microsoft.Office.Interop.Outlook;
using Microsoft.Office.Tools.Outlook;
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 System.Net;
using System.Net.Mail;
using System.Runtime.InteropServices;
namespace OutlookControll
{
public enum MailSendType
{
NoSend,
Normal,
WithAdverts,
WithCoupon
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public MailSendType SendType = MailSendType.NoSend;
private void Btn_ShowSecondForm_Click(object sender, EventArgs e)
{
AddItemsForm f2 = new AddItemsForm();
f2.ShowDialog();
this.Hide();
}
private void Btn_cancel_Click(object sender, EventArgs e)
{
Button Btn_cancel_Click = new Button();
Btn_cancel_Click.DialogResult = DialogResult.Cancel;
this.Hide();
}
public void Btn_standard_Click(object sender, EventArgs e)
{
Button Btn_standard_Click = new Button();
Btn_standard_Click.DialogResult = DialogResult.OK;
Controls.Add(Btn_standard_Click);
SendType = MailSendType.Normal;
this.Hide();
}
}
Btn_standard_Click.DialogResult = DialogResult.OK
可以设置在Properties
-> Behavior
-> DialogResult
-> OK, Cancel, Abort等
我可以考虑 3 种可能的情况:
- 按发送 > 弹出表单 > Select 表单上的选项 > 修改电子邮件内容 > 发送电子邮件
- 按发送 > 弹出表单 > 表单上的 Select 选项 > 创建并发送新电子邮件(发送 1 封或多封新电子邮件)(丢弃旧电子邮件) >发送电子邮件
- 按发送 > 弹出表单 > 表单上的 Select 选项 > 创建并发送新电子邮件(发送 1 封或多封新电子邮件)(发送旧电子邮件) >发送电子邮件
请注意,一旦修改邮件内容就意味着修改所有内容。更改发件人更改主题等。因此,如果您想创建一封新电子邮件并丢弃旧电子邮件,选项 1 仍然可以完全操纵原始电子邮件。
允许用户select相关选项的对话框。
注意:放置表单按钮时,请确保在属性检查器的行为下设置 DialogResult
选项。这允许在单击自动关闭并从对话框返回的按钮之一后返回 DialogResult:OK
。
public enum MailSendType
{
NoSend,
Normal,
WithAdverts,
WithCoupon
}
public partial class SendItemForm : Form
{
public SendItemForm()
{
InitializeComponent();
}
public MailSendType SendType = MailSendType.NoSend;
private void button1_Click(object sender, EventArgs e)
{
SendType = MailSendType.Normal;
}
private void button2_Click(object sender, EventArgs e)
{
SendType = MailSendType.WithAdverts;
}
}
选项 1:仅修改电子邮件的内容
注意显示 f.ShowDialog()
而不是 f.Show()
这会阻止当前线程继续发送操作并等待用户 select 表单上的按钮。对话框中的 f.SendType
已设置并用于指示用户 select 编辑了哪个选项。使用 ProcessEmail
可以操纵电子邮件,并且 return false
会导致在 false
向下传播到父函数 Cancel = false
时发送被操纵的电子邮件(不要取消发送)。
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
// create a global event listener for sending items
Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);
}
// this function is used to modify the mail object before sending it (More variables could be added to extend the functionality)
private bool ProcessEmail(Outlook.MailItem mailItem, MailSendType sendType)
{
switch (sendType)
{
case MailSendType.Normal:
return false; // send the mail as is don't mainpulate the mailItem variable
case MailSendType.WithAdverts:
mailItem.BCC += "ad@server.xyz";
mailItem.HTMLBody += @"<b>Some bold text at the end :)</b>";
mailItem.HTMLBody += @"</img src='https://server.xyz/ad1.png'>";
return false; // send the mail
case MailSendType.WithCoupon:
mailItem.CC += "coupon@server.xyz";
mailItem.HTMLBody += @"</img src='https://server.xyz/coupon1.png'>";
return false; // send the mail
// by default don't send the mail
default:
return true;
}
}
private void Application_ItemSend(object Item, ref bool Cancel)
{
if (Item is Outlook.MailItem) // ensures Item is a mail item
{
using (SendItemForm f = new SendItemForm()) // creates the form
if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK) // shows the form as a dialog
//if statement ensures the process will only proceed if an OK is returned
//(The form has a cancel button or it could crash or anything else)
Cancel = ProcessEmail((Outlook.MailItem)Item, f.SendType); // process the email with the SendType
}
}
选项 2/3 发送新电子邮件
此方法重点介绍了如何在 Outlook 中发送新电子邮件。注意:已测试使用 MailItem.Send()
发送电子邮件并且它不会再次调用 Application_ItemSend
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);
}
private void SendNewEmail(string to, string greeting, MailSendType sendType)
{
Outlook.MailItem newMailItem = Application.CreateItem(Outlook.OlItemType.olMailItem);
newMailItem.To = to;
newMailItem.SendUsingAccount = Application.Session.Accounts[1]; // Optional can leave blank to send from default account (Array starts at 1)
newMailItem.Subject = "New Mail";
newMailItem.Body = $"{greeting} {newMailItem.To}\nExample Body from {sendType.ToString()}";
// Part of Original answer but it's not relevant. However I will leave it in the event that it is of use to someone
//((Outlook.ItemEvents_10_Event)newMailItem).Send += (ref bool Cancel) => { /*do nothing*/ };
newMailItem.Send(); // send the mail
}
private void Application_ItemSend(object Item, ref bool Cancel)
{
if (Item is Outlook.MailItem) // ensures Item is a mail item
{
using (SendItemForm f = new SendItemForm()) // creates the form
if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK) // shows the form as a dialog
{
//if statement ensures the process will only proceed if an OK is returned
//(The form has a cancel button or it could crash or anything else)
// send 3 mails
SendNewEmail("admin1@server.xyz", "Hi", f.SendType);
SendNewEmail("admin2@server.xyz", "Hello", MailSendType.Normal);
SendNewEmail("admin3@server.xyz", "Yo", f.SendType);
// either send or don't send the orginal one
// by default Cancel is set to false (So by default the message will send)
// send the 3 mails and send the original one typed up by the user
//Cancel = false;
// send the 3 mails and do not send the original one currently typed up by the user
// Cancel = true;
}
}
}
在这 2 个示例和 f.ShowDialog()
设置之间,您应该能够找到您寻求的解决方案。您还可以通过修改原始电子邮件并发送额外的电子邮件来混合搭配。