AddOn 编程和 Outlook AddIn2





3.00/5 (1投票)
AddIn - Outlook AddIn 区域、视图、规则和报告的 AddOn 编程及示例
引言
我发现在互联网上关于 OutlookAddIn 编程的信息不足,因此我决定写这篇文章。我搜索了许多网站,并阅读了一些关于 AddIn 编程的有趣书籍。在我完成了一些专业工作后,我为新的 AddIn 程序员找到了一些关键解决方案,现在我将它们分享出来。
本文将介绍一些关键且有趣的技术细节。
目录
- 区域
- 事件处理程序
- 报告
- 任务、邮件和约会管理
- 操作系统和版本检测
- 视图
- 规则
启动
#region Definitions
public static Outlook.Inspectors inspectors;
public static string _targetPath = "C:\\Users\\" + "testing\\";
public static string _liveMeeting = "C:\\ Logs\\LiveMeetings.txt";
public static bool _regionSender = false;
private static string _operationSystemVersion = string.Empty;
private static Timer _tm = new Timer();
private static bool _timerSwitch = false;
private static ThisAddIn _instance = null;
private static bool _manuelCancel = false;
private static Outlook.AppointmentItem _aitm = null;
private static bool _isLiiveMessageShowing = true;
private static string _targetPathWin7 = "C:\\Users\\" + Environment.UserName +
"\\AppData\\Roaming\\Comp\\MeetingTools\\";
private static string _targetPathXp = "C:\\Documents and Settings\\" +
Environment.UserName + "\\Application Data\\Comp\\MeetingTools\\";
private int _meetingCount = 0;
private int _meetingCountOwner = 0;
private int _livmeetingCount = 0;
private double _weeklyWorkingHours = 45;
private double _dailyWorkingPercentace = 0;
private TimeSpan _totalMeetingTime = new TimeSpan();
private string _logRoute = "C:\\Logs";
private string _logLocation = "C:\\Logs\\Reports.txt";
int counter = 0;
bool _senderTriggered = false;
private static DataSet _ds = new DataSet();
private static DataSet _dSet = new DataSet();
AppointmentItem ai;
static bool _deleteTrigered = false;
static string _domainName = "comuty";
bool _isOkeMailSettings = true;
#endregion
AddIn 以某些事件处理程序开始,因为如果程序员想在 Office 程序中根据某些条件执行操作,它会向程序员提供一个事件,程序员可以处理该事件并根据其目标使用它。事件处理程序在启动时如下所示。
private void InternalStartup()
{
//CreateActionRule();
this.Startup += new System.EventHandler(ThisAddIn_Startup);
this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
}
在此过程之后,程序员可以使用后续步骤。
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
if (_operationSystemVersion.Equals(string.Empty))
_operationSystemVersion = FindVersion();
if (_operationSystemVersion.Equals("XP"))
_targetPath = _targetPathXp;
else if (_operationSystemVersion.Equals("Win7"))
_targetPath = _targetPathWin7;
//CreateCustomAksiyonViewIfNotExist();
inspectors = this.Application.Inspectors;
inspectors.NewInspector +=
new Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(
inspectors_NewInspector);
_instance = this;
}
业务逻辑
在工具栏或上下文菜单中插入按钮、捕获某些屏幕以根据需要更改其算法并满足全部要求是 AddIn 程序中的主要因素。因此,我们可以编写所有这些阶段,从我们在启动事件中处理过的 Inspector 开始。Current Item 在事件触发时为我们提供了实质性元素。在本例中,我处理了 Appointment Item,如下所示。我将使用 timer
对象在用户输入的当前窗口中绘制图形。在此操作之后,我将调用 ReportInspector
函数进行检查,如果存在任何报告,我将作为邮件将此报告发送给当前用户。
void inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)
{
_deleteTrigered = false;
_manuelCancel = false;
_senderTriggered = false;
if (_isOkeMailSettings)
{
SetDataSet();
_isLiiveMessageShowing = IsLiveMeetingShowing(DateTime.Now, Inspector);
ReportInspector(DateTime.Now, Inspector);
}
Object anitem = (Outlook.AppointmentItem)Inspector.CurrentItem;
ai = (Outlook.AppointmentItem)Inspector.CurrentItem;
if (anitem != null)
{
_aitm = (Outlook.AppointmentItem)anitem;
if (_aitm.Body == null)
{
_tm.Interval = 10;
_tm.Tick += new EventHandler(tm_Tick);
_timerSwitch = true;
_tm.Start();
}
}
}
当我们处理了新的约会窗口后,就可以通过使用某些表格和图形 COM 对象来捕获其内容,从而创建一个新的特殊设计。在这里,内容是 Document
类。
void tm_Tick(object sender, EventArgs e)
{
if (_timerSwitch)
{
_timerSwitch = false;
_tm.Stop();
object ranger = (
Application.ActiveInspector().WordEditor as
Microsoft.Office.Interop.Word.DocumentClass).Application.Selection.Range;
object linToFile = true;
object saveWithDocument = true;
string path = System.AppDomain.CurrentDomain.BaseDirectory.ToString();
((Application.ActiveInspector().WordEditor as
Microsoft.Office.Interop.Word.DocumentClass)).InlineShapes.
AddPicture(path + "\\Resources\\comunuty.jpg",
ref linToFile, ref saveWithDocument, ref ranger);
Microsoft.Office.Interop.Word.Range range1 = (
Application.ActiveInspector().WordEditor as
Microsoft.Office.Interop.Word.DocumentClass).Application.Selection.Range;
range1.Start = 0;
range1.Font.Size = 12;
range1.Font.Name = "Calibri";
range1.Orientation = Microsoft.Office.Interop.Word.
WdTextOrientation.wdTextOrientationHorizontal;
range1.Text = "\r\v\v\v\v\v\v\v\v\v\r";
range1.Font.Color = Microsoft.Office.Interop.Word.WdColor.wdColorBlack;
range1.End = 1;
Microsoft.Office.Interop.Word.Range range = (
Application.ActiveInspector().WordEditor as
Microsoft.Office.Interop.Word.DocumentClass).Application.Selection.Range;
range.Start = 1;
range.Font.Size = 12;
range.Font.Name = "Calibri";
range.Orientation = Microsoft.Office.Interop.
Word.WdTextOrientation.wdTextOrientationHorizontal;
range.Text = " Header";
range.Font.Bold = 1;
range.Font.Italic = 1;
range.End = 2;
((Outlook.ItemEvents_10_Event)Application.ActiveInspector().
CurrentItem).BeforeDelete +=
new ItemEvents_10_BeforeDeleteEventHandler(ThisAddIn_BeforeDelete);
this.Application.ItemSend += new ApplicationEvents_11_ItemSendEventHandler
(Application_ItemSend);
((Outlook.ItemEvents_10_Event)Application.
ActiveInspector().CurrentItem).Close +=
new ItemEvents_10_CloseEventHandler(ThisAddIn_Close);
}
}
Close
和 Send
事件处理程序在用户交互发送或关闭此项目时提供了一些特殊行为。在关闭和发送项目时,我使用了许多控制代码。我在 Close
事件中的算法中识别了用户按下了哪个按钮,因为 Close
事件在用户在用户界面中更改的每种情况下都会工作。
void Application_ItemSend(object Item, ref bool Cancel)
{
try
{
this.Application.ItemSend -= new ApplicationEvents_11_ItemSendEventHandler(
Application_ItemSend);
bool _mayReturn = false;
if (!_domainName.Equals("comunuty") ||
(Application.ActiveInspector().CurrentItem as AppointmentItem) == null)
return;
_senderTriggered = true;
if (_regionSender)
{
_regionSender = false;
Cancel = false;
return;
}
if ((
Application.ActiveInspector().CurrentItem as AppointmentItem).
MeetingStatus.ToString().Equals("olMeetingCanceled"))
return;
((Application.ActiveInspector().WordEditor as
Microsoft.Office.Interop.Word.DocumentClass)).WebOptions.AllowPNG = true;
string attendees = GetCurrentUserAddress() + ";" +
GetRecipients(Application.ActiveInspector().
CurrentItem as Outlook.AppointmentItem);
//MessageBox.Show("req:" + attendees);
if (attendees.Contains("@"))
{
foreach (DataRow dr in _dSet.Tables[0].Rows)
{
if (dr.ItemArray[0].ToString().TrimStart().TrimEnd().Equals(attendees))
{
attendees = dr.ItemArray[0].ToString();
string worker = dr.ItemArray[0].ToString();
break;
}
}
}
if (!Cancel && IsLiveMeeting(attendees,
(Application.ActiveInspector().CurrentItem as Outlook.AppointmentItem).Location))
{
WarningLiveMeeting wlm = new WarningLiveMeeting();
wlm.StartPosition = FormStartPosition.CenterScreen;
if (wlm.ShowDialog() == DialogResult.OK)
{
if (wlm._sellection)
{
Cancel = true;
return;
}
_mayReturn = true;
}
}
if (!_manuelCancel)
{
int sameAppointment = 0;
WarningWindow1 ww1 = null;
List<AppointmentItem> items = GetAppointments((
Application.ActiveInspector().CurrentItem as AppointmentItem).Start,
(Application.ActiveInspector().CurrentItem as AppointmentItem).End);
(Application.ActiveInspector().CurrentItem as AppointmentItem).Save();
string uniqId1 = (
Application.ActiveInspector().CurrentItem as AppointmentItem).EntryID;
AppointmentItem eklenecekEleman = (
Application.ActiveInspector().CurrentItem as AppointmentItem);
bool switchReturn = false;
bool equalityControlSwitch = false;
bool isCase1 = false;
try
{
foreach (AppointmentItem second in items)
{
TimeSpan scale1 = new TimeSpan(0, 0, 0);
TimeSpan scale2 = new TimeSpan(0, 10, 0);
TimeSpan storage = new TimeSpan(0, 0, 0);
TimeSpan oneHour = new TimeSpan(1, 0, 0);
string uniqId2 = second.EntryID;
if (!uniqId1.Equals(uniqId2))
{
if (!equalityControlSwitch)
{
equalityControlSwitch = true;
int ind = 0;
foreach (AppointmentItem guncelEleman in items)
{
bool yenininSonuBasiIleEskininSonuBasininCakismasi = false;
if (ind + 1 <= items.Count)
{
int difference = 99999999;
AppointmentItem biSonrakiEleman = null;
foreach (AppointmentItem sonraki in items)
{
int guncelElemanDateValue = (eklenecekEleman.Start.Year * 8760) +
(eklenecekEleman.Start.Month * 720) +
(eklenecekEleman.Start.Day * 24) + eklenecekEleman.Start.Hour;
int sonrakiElemanDateValue = (sonraki.Start.Year * 8760) +
(sonraki.Start.Month * 720) + (sonraki.Start.Day * 24) +
sonraki.Start.Hour;
if (guncelElemanDateValue < sonrakiElemanDateValue)
{
if (difference > sonrakiElemanDateValue -
guncelElemanDateValue)
{
difference = sonrakiElemanDateValue -
guncelElemanDateValue;
biSonrakiEleman = sonraki;
}
}
}
if (biSonrakiEleman == null)
continue;
if (eklenecekEleman.Start == guncelEleman.End &&
eklenecekEleman.End == biSonrakiEleman.Start)
yenininSonuBasiIleEskininSonuBasininCakismasi = true;
}
// CASE1
if (yenininSonuBasiIleEskininSonuBasininCakismasi)
;
// CASE1
if (yenininSonuBasiIleEskininSonuBasininCakismasi &&
(eklenecekEleman.End.Ticks - eklenecekEleman.Start.Ticks) >
oneHour.Ticks &&
!guncelEleman.EntryID.Equals(eklenecekEleman.EntryID)
)
{
ww1 = new WarningWindow1();
ww1.StartPosition = FormStartPosition.CenterScreen;
if (ww1.ShowDialog() == DialogResult.OK)
{
isCase1 = true;
switchReturn = true;
if (ww1._button == "2")
{
storage = eklenecekEleman.End - eklenecekEleman.Start;
eklenecekEleman.Start = eklenecekEleman.Start + scale2;
eklenecekEleman.End = eklenecekEleman.End - (scale2 + scale2);
if (eklenecekEleman.RequiredAttendees == null ||
eklenecekEleman.RequiredAttendees.Equals(string.Empty))
eklenecekEleman.Save();
//else eklenecekEleman.Send();
return;
}
else if (ww1._button == "3")
{
Cancel = true;
return;
}
else if (ww1._button == "1")
{
return;
}
}
}
else if (yenininSonuBasiIleEskininSonuBasininCakismasi &&
(eklenecekEleman.End.Ticks - eklenecekEleman.Start.Ticks)
<= oneHour.Ticks &&
!guncelEleman.EntryID.Equals(eklenecekEleman.EntryID)
)
{
return;
}
ind++;
}
if (switchReturn)
break;
}
}
else
{
// if comparsion is happening for the same appointment
if (sameAppointment > 1)
{
ww1 = new WarningWindow1();
if (ww1.ShowDialog() == DialogResult.OK)
{
if (ww1._sellection)
{
_manuelCancel = true;
Cancel = true;
}
}
break;
}
sameAppointment++;
}
}
}
catch (System.Exception ex)
{
string mes = ex.Message;
}
// Case2 and Case3
if (!isCase1)
{
bool equalityControlSwitch2 = false;
string uniqId11 = (Application.ActiveInspector().
CurrentItem as AppointmentItem).EntryID;
foreach (AppointmentItem second in items)
{
TimeSpan scale1 = new TimeSpan(0, 0, 0);
TimeSpan scale2 = new TimeSpan(0, 10, 0);
TimeSpan storage = new TimeSpan(0, 0, 0);
TimeSpan oneHour = new TimeSpan(1, 0, 0);
string uniqId2 = second.EntryID;
if (!uniqId11.Equals(uniqId2))
{
if (!equalityControlSwitch2)
{
equalityControlSwitch2 = true;
int ind = 0;
foreach (AppointmentItem guncelEleman in items)
{
//******************
bool yenininBasiIleEskininSonuCakismasi = false;
bool yenininSonuIleEskininBasininCakismasi = false;
//CASE2
if (eklenecekEleman.Start == guncelEleman.End)
yenininBasiIleEskininSonuCakismasi = true;
//CASE3
else if (eklenecekEleman.End == guncelEleman.Start)
yenininSonuIleEskininBasininCakismasi = true;
//CASE2
if (yenininBasiIleEskininSonuCakismasi &&
!guncelEleman.EntryID.Equals(eklenecekEleman.EntryID)
)
{
ww1 = new WarningWindow1();
ww1.StartPosition = FormStartPosition.CenterScreen;
if (ww1.ShowDialog() == DialogResult.OK)
{
switchReturn = true;
if (ww1._button == "2")
{
DateTime endd = eklenecekEleman.End;
eklenecekEleman.Start = eklenecekEleman.Start + scale2;
eklenecekEleman.End = endd;
if (eklenecekEleman.RequiredAttendees == null ||
eklenecekEleman.RequiredAttendees.Equals(string.Empty))
eklenecekEleman.Save();
//else eklenecekEleman.Send();
return;
}
else if (ww1._button == "3")
{
Cancel = true;
return;
}
else if (ww1._button == "1")
{
return;
}
}
}
// CASE3
if (yenininSonuIleEskininBasininCakismasi &&
!guncelEleman.EntryID.Equals(eklenecekEleman.EntryID)
)
{
ww1 = new WarningWindow1();
ww1.StartPosition = FormStartPosition.CenterScreen;
if (ww1.ShowDialog() == DialogResult.OK)
{
switchReturn = true;
if (ww1._button == "2")
{
DateTime startt = eklenecekEleman.Start;
eklenecekEleman.End = eklenecekEleman.End - scale2;
eklenecekEleman.Start = startt;
if (eklenecekEleman.RequiredAttendees == null ||
eklenecekEleman.RequiredAttendees.Equals(string.Empty))
eklenecekEleman.Save();
//else eklenecekEleman.Send();
return;
}
else if (ww1._button == "3")
{
Cancel = true;
return;
}
else if (ww1._button == "1")
{
return;
}
}
}
//****************
ind++;
}
if (switchReturn)
break;
}
}
else
{
// if comparsion is happening for the same appointment
if (sameAppointment > 1)
{
ww1 = new WarningWindow1();
if (ww1.ShowDialog() == DialogResult.OK)
{
if (ww1._sellection)
{
_manuelCancel = true;
Cancel = true;
}
}
break;
}
sameAppointment++;
}
}
}
}
if (AppointmentRegion._inProgress)
AppointmentRegion._inProgress = false;
//(((Application.ActiveInspector().WordEditor as
// Microsoft.Office.Interop.Word.DocumentClass)).Content as
// Outlook.MailItem).BodyFormat = OlBodyFormat.olFormatUnspecified;
if (_mayReturn)
return;
}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString());
}
报告
我们可以以某种方式获得定期的统计报告。此外,我们还可以从 Exchange Server 获取一些报告。我将向您展示一些通过此场景获得的个人报告。
GetMonthlyReport
函数获取默认的 MAPI 文件夹,以确定用户在上个月发布了多少次会议以及花费了多少时间。
public List<Outlook.AppointmentItem> GetMonthlyReport()
{
counter = 0;
Outlook.MAPIFolder mpiFolder =
Application.GetNamespace("MAPI").GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
var appItems = new List<Outlook.AppointmentItem>();
_meetingCountOwner = 0;
_meetingCount = 0;
_totalMeetingTime = new TimeSpan(0, 0, 0);
_livmeetingCount = 0;
DateTime startdate = new DateTime
(DateTime.Now.Date.Year, DateTime.Now.Date.Date.Month - 1, 1, 0, 0, 0);
DateTime ddd = new DateTime(DateTime.Now.Date.Year, DateTime.Now.Date.Month, 1, 0, 0, 0);
DateTime enddate = ddd.AddDays(-1);
mpiFolder.Items.Sort("[Start]", false);
mpiFolder.Items.IncludeRecurrences = true;
String sCriteria;
string sDate = startdate.Day.ToString() + "." +
startdate.Month.ToString() + "." + startdate.Year.ToString() + " 00:00";
string eDate = enddate.Day.ToString() + "." +
enddate.Month.ToString() + "." + enddate.Year.ToString() + " 23:59";
sCriteria = "[Start] < '" + eDate + "' and [End] > '" + sDate + "'";
Outlook.Items oRestrictedItems = mpiFolder.Items.Restrict(sCriteria);
oRestrictedItems.Sort("[Start]", false);
oRestrictedItems.IncludeRecurrences = true;
foreach (object obj in oRestrictedItems)
{
counter++;
AppointmentItem appointment = obj as AppointmentItem;
if (appointment == null || (appointment.Start.DayOfWeek == DayOfWeek.Saturday ||
appointment.Start.DayOfWeek == DayOfWeek.Sunday))
continue;
if (appointment != null)
{
if (true)
{
DateTime endOfTheDay = new DateTime(appointment.Start.Date.Year,
appointment.Start.Date.Month, appointment.Start.Date.Day, 17, 0, 0);
if (appointment.End.Hour < 8 || appointment.End.Hour > 17
|| (appointment.End.Hour - appointment.Start.Hour) > 5
|| appointment.End.Day - appointment.Start.Day > 0)
{
continue;
}
bool isOwnerMeeting = false;
if (appointment.RequiredAttendees == null ||
appointment.RequiredAttendees.Equals(string.Empty))
{
_meetingCountOwner++;
isOwnerMeeting = true;
}
if (appointment.MeetingStatus == OlMeetingStatus.olMeeting ||
appointment.MeetingStatus == OlMeetingStatus.olMeetingReceived ||
appointment.RequiredAttendees == null ||
appointment.RequiredAttendees.Equals(string.Empty))
{
_meetingCount++;
if (!isOwnerMeeting)
_totalMeetingTime += appointment.End - appointment.Start;
}
if (appointment.Location != null &&
(appointment.Location.Contains("Live Meeting") ||
appointment.Location.Contains("LiveMeeting") ||
appointment.Location.Contains("livemeeting") ||
appointment.Location.Contains("live meeting")))
_livmeetingCount++;
}
}
}
return appItems;
}
此情况还会查找他正在进行的会议和已接受的会议。我们可以通过检查其周期性后台来在其他文件夹中使用此例程。例如,获取精选的约会、任务和邮件,如下所示。
public List<Outlook.AppointmentItem> GetFeaturedAppointments()
{
Outlook.MAPIFolder mpiFolder =
Application.GetNamespace("MAPI").GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
var appItems = new List<Outlook.AppointmentItem>();
foreach (object obj in mpiFolder.Items)
{
AppointmentItem appointment = obj as AppointmentItem;
if (appointment != null)
{
if (appointment.Start > DateTime.Now - new TimeSpan(0, 30, 0))
appItems.Add(appointment);
}
}
return appItems;
}
此外,我们还可以找出当前用户的地址。这比我想分享的更重要。
private string GetCurrentUserAddress()
{
try
{
Outlook.AddressEntry ae = Application.Session.CurrentUser.AddressEntry;
switch (Application.Session.CurrentUser.DisplayType)
{
case (Outlook.OlDisplayType.olDistList):
{
ae = Application.Session.CurrentUser.AddressEntry;
foreach (Outlook.AddressEntry aEnt in ae.Members)
{
if (aEnt.DisplayType != Outlook.OlDisplayType.olDistList &&
aEnt.DisplayType != Outlook.OlDisplayType.olPrivateDistList)
{
string smtp = aEnt.GetExchangeUser().PrimarySmtpAddress;
return smtp;
}
}
} break;
case (Outlook.OlDisplayType.olPrivateDistList):
{
ae = Application.Session.CurrentUser.AddressEntry;
foreach (Outlook.AddressEntry aEnt in ae.Members)
{
if (aEnt.DisplayType != Outlook.OlDisplayType.olDistList &&
aEnt.DisplayType != Outlook.OlDisplayType.olPrivateDistList)
{
string smtp = aEnt.Address;
return smtp;
}
}
} break;
case (Outlook.OlDisplayType.olUser):
{
string smtp = "";
ae = Application.Session.CurrentUser.AddressEntry;
if (ae.GetExchangeUser() == null)
{
smtp = ae.Address;
return smtp;
}
else
{
smtp = ae.GetExchangeUser().PrimarySmtpAddress;
return smtp;
}
}
default:
{
string smtp = "";
ae = Application.Session.CurrentUser.AddressEntry;
if (ae.GetExchangeUser() == null)
{
smtp = ae.Address;
return smtp;
}
else
{
smtp = ae.GetExchangeUser().PrimarySmtpAddress;
return smtp;
}
}
}
return "";
}
catch (System.Exception ex)
{
throw ex;
}
}
public List<Outlook.TaskItem> GetFeaturedTasks()
{
Outlook.MAPIFolder mpiFolder = Application.GetNamespace("MAPI").
GetDefaultFolder(OlDefaultFolders.olFolderTasks);
var taskItems = new List<Outlook.TaskItem>();
foreach (object obj in mpiFolder.Items)
{
TaskItem task = obj as TaskItem;
if (task != null)
{
taskItems.Add(task);
}
}
return taskItems;
}
public List<Outlook.MailItem> GetFeaturedMails()
{
Outlook.MAPIFolder mpiFolder = Application.GetNamespace
("MAPI").GetDefaultFolder(OlDefaultFolders.olFolderSentMail);
var mailItems = new List<Outlook.MailItem>();
foreach (object obj in mpiFolder.Items)
{
MailItem mail = obj as MailItem;
if (mail != null)
{
mailItems.Add(mail);
}
}
return mailItems;
}
版本和操作系统检测
操作系统检测超出了本文的范围,但我只想向您展示如何检测此 AddIn 的版本,以及我们如何根据其他操作系统和 Office 的其他版本来编写 AddIn。我将在下面展示操作系统检测例程。
private string FindVersion()
{
System.OperatingSystem osInfo = System.Environment.OSVersion;
string operatingSystem = "Unknown";
switch (osInfo.Platform)
{
case System.PlatformID.Win32Windows:
// Current OS is Windows - can be Windows95, 98 or ME
switch (osInfo.Version.Minor)
{
case 0:
operatingSystem = "Windows 95";
break;
case 10:
operatingSystem = "Windows 98";
break;
case 90:
operatingSystem = "Windows Me";
break;
}
break;
case System.PlatformID.Win32NT:
// Current OS is Windows NT, 2000 or XP
switch (osInfo.Version.Major)
{
case 3:
operatingSystem = "Windows NT 3.51";
break;
case 4:
operatingSystem = "Windows NT 4.0";
break;
case 5:
if (osInfo.Version.Minor == 0)
operatingSystem = "Windows 2000";
else
operatingSystem = "XP";
break;
case 6:
operatingSystem = "Win7";
break;
}
break;
}
return operatingSystem;
}
一旦我们获得了系统知识,我们就可以根据其属性编写任何机会。无论如何,这里真正重要的点是我准备好的版本检测,如下所示。
string version = ((Microsoft.Office.Interop.Outlook.ApplicationClass)(((
Microsoft.Office.Interop.Outlook.InspectorClass)
(_inspector)).Application)).Version;
int preVer = Convert.ToInt32(version.Substring(0, 2));
当 preVer
指示 12 时,Office 版本为 2007;当 preVer
指示 12 时,Office 版本为 2007。
我从这项工作中了解到,Microsoft Office 2007 Sp1 对 Office 2007 对象模型的 Close
和 Save
事件支持有一个修复程序。即使是 Office 2010 还没有这个机会。
视图
视图提供了 Outlook 中自定义屏幕和操作管理。用户可以从工具菜单进行设置,但我想用 C# 以编程方式准备此功能。
private void CreateCustomAksiyonViewIfNotExist()
{
Application.ActiveExplorer().CurrentFolder.CustomViewsOnly = true;
Outlook.View lastView = Application.ActiveExplorer().CurrentFolder.CurrentView;
Outlook.View newView = null;
try
{
bool isthere = false;
Application.ActiveExplorer().NavigationPane.CurrentModule =
Application.ActiveExplorer().NavigationPane.Modules[4];
foreach (Outlook.View view in Application.ActiveExplorer().CurrentFolder.Views)
{
if (view.Name.Equals("Actions"))
isthere = true;
}
if (!isthere)
{
newView = Application.ActiveExplorer().CurrentFolder.Views.Add("Actions",
Outlook.OlViewType.olTableView,
Outlook.OlViewSaveOption.olViewSaveOptionThisFolderEveryone);
newView.Filter = "\"urn:schemas:httpmail:subject\" LIKE '% Actions %'";
newView.Save();
newView.Apply();
}
}
catch (System.ArgumentException ex)
{
MessageBox.Show(ex.Message);
return;
}
Application.ActiveExplorer().NavigationPane.CurrentModule =
Application.ActiveExplorer().NavigationPane.Modules[1];
}
规则
规则类似于视图的用户自定义,但规则仅依赖于操作以及发布操作时的特殊内容。
void CreateActionRule()
{
Rules ruless = this.Application.Session.DefaultStore.GetRules();
for (int k = 1; k < ruless.Count; k++)
{
if (ruless[k].Name.Equals("ActionAndDecissionRule"))
return;
}
Outlook.MAPIFolder inbox = this.Application.Session.GetDefaultFolder(
Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
inbox.Folders.Add("Aksiyon&Kararlar",
Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
Outlook.MAPIFolder targetfolder = inbox.Folders["Aksiyon&Kararlar"];
Rules rules = this.Application.Session.DefaultStore.GetRules();
Outlook.Rule rule = rules.Create("ActionAndDecissionRule",
Microsoft.Office.Interop.Outlook.OlRuleType.olRuleReceive);
Outlook.TextRuleCondition sub = rule.Conditions.Body;
sub.Enabled = true;
sub.Text = new string[] { "ToplantisiKararlari-iyitoplantiKontrol" };
Outlook.MoveOrCopyRuleAction movecopy = rule.Actions.MoveToFolder;
movecopy.Enabled = true;
movecopy.Folder = targetfolder;
rule.Execute(true, inbox, false,
Outlook.OlRuleExecuteOption.olRuleExecuteUnreadMessages);
rules.Save(false);
}
结论
总之,我研究了许多文档,但我没有找到关于此主题的足够信息,并且在该领域没有免费书籍。我相信当有人想编写 AddIn 时,这些信息将非常有用。
附录
- WPF 到 AddIns: http://msdn.microsoft.com/en-us/library/bb410039.aspx
- Add In RegionForm: http://www.csharpnedir.com/articles/read/?id=945
- Reminders: http://ru2nuts.livejournal.com/77689.html
- Reports: http://blogs.msdn.com/coding4fun/archive/2006/11/20/1111248.aspx
- Reports2: http://msdn.microsoft.com/en-us/library/dd492013.aspx
- Attachment: http://social.msdn.microsoft.com/Forums/en-US/vsto/thread/186ddb96-8780-4f92-8f0f-ab6698985220
- PropertyAccesor: http://us.generation-nt.com/get-formatted-text-appointmentitem-body-help-75158652.html
- Install shield CustomActions: http://geekswithblogs.net/Gaurav/archive/2006/05/30/80082.aspx
- Clickone Installment: http://msdn.microsoft.com/en-us/library/bb821233.aspx
- Creating Custom Views: http://msdn.microsoft.com/en-us/library/aa155658(office.10).aspx
- Customization View Types: http://msdn.microsoft.com/en-us/library/aa204771(office.11).aspx
- Outlook 2007 Significant: http://msdn.microsoft.com/en-us/library/bb226714(office.12).aspx
- OutLook Folders and Exchange Connection: http://www.c-sharpcorner.com/UploadFile/rambab/OutlookIntegration10282006032802AM/OutlookIntegration.aspx
- Exchange API Usage: http://msdn.microsoft.com/en-us/library/dd637749(EXCHG.80).aspx
- Rules: http://msdn.microsoft.com/en-us/library/bb226714(office.12).aspx