728x90
728x170
▶ RibbonContextMenu.xml
<?xml version="1.0" encoding="UTF-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="customUI_onLoad">
<contextMenus>
<contextMenu idMso="ContextMenuMailItem">
<button id="saveEMLFileButton"
label="EML 파일 저장하기"
onAction="contextMenu_onAction" />
</contextMenu>
</contextMenus>
</customUI>
728x90
▶ RibbonContextMenu.cs
using Microsoft.Office.Core;
using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using MimeKit;
namespace TestProject
{
/// <summary>
/// 리본 컨텍스트 메뉴
/// </summary>
[ComVisible(true)]
public class RibbonContextMenu : IRibbonExtensibility
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 리본 UI
/// </summary>
private IRibbonUI ribbonUI;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - RibbonContextMenu()
/// <summary>
/// 생성자
/// </summary>
public RibbonContextMenu()
{
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
//////////////////////////////////////////////////////////////////////////////// Event
#region 커스텀 UI 로드시 처리하기 - customUI_onLoad(ribbonUI)
/// <summary>
/// 커스텀 UI 로드시 처리하기
/// </summary>
/// <param name="ribbonUI">리본 UI</param>
public void customUI_onLoad(IRibbonUI ribbonUI)
{
this.ribbonUI = ribbonUI;
}
#endregion
#region 컨텍스트 메뉴 작업시 처리하기 - contextMenu_onAction(ribbonControl)
/// <summary>
/// 컨텍스트 메뉴 작업시 처리하기
/// </summary>
/// <param name="ribbonControl">리본 컨트롤</param>
public void contextMenu_onAction(IRibbonControl ribbonControl)
{
switch(ribbonControl.Id)
{
case "saveEMLFileButton" :
try
{
dynamic itemCollection = ribbonControl.Context;
foreach(dynamic item in itemCollection)
{
if(item is MailItem mailItem)
{
SaveEMLFile(mailItem, "d:\\test.eml");
}
}
}
catch(System.Exception exception)
{
MessageBox.Show($"예외가 발생하였습니다.\r\n{exception.ToString()}");
}
break;
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region (IRibbonExtensibility) 커스텀 UI 구하기 - GetCustomUI(ribbonID)
/// <summary>
/// 커스텀 UI 구하기
/// </summary>
/// <param name="ribbonID">리본 ID</param>
/// <returns>커스텀 UI</returns>
public string GetCustomUI(string ribbonID)
{
return ribbonID.Equals("Microsoft.Outlook.Explorer") ? GetResourceText("TestProject.RibbonContextMenu.xml") : null;
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Function
#region 리소스 텍스트 구하기 - GetResourceText(resourceName)
/// <summary>
/// 리소스 텍스트 구하기
/// </summary>
/// <param name="resourceName">리소스명</param>
/// <returns>리소스 텍스트</returns>
private static string GetResourceText(string resourceName)
{
Assembly assembly = Assembly.GetExecutingAssembly();
string[] resourceNameArray = assembly.GetManifestResourceNames();
int count = resourceNameArray.Length;
for(int i = 0; i < count; ++i)
{
if(string.Compare(resourceName, resourceNameArray[i], StringComparison.OrdinalIgnoreCase) == 0)
{
using(StreamReader reader = new StreamReader(assembly.GetManifestResourceStream(resourceNameArray[i])))
{
if(reader != null)
{
return reader.ReadToEnd();
}
}
}
}
return null;
}
#endregion
#region EML 파일 저장하기 - SaveEMLFile(mailItem, filePath)
/// <summary>
/// EML 파일 저장하기
/// </summary>
/// <param name="mailItem">메일 항목</param>
/// <param name="filePath">파일 경로</param>
private void SaveEMLFile(MailItem mailItem, string filePath)
{
System.Net.Mail.MailMessage mailMessage = new System.Net.Mail.MailMessage();
mailMessage.Subject = mailItem.Subject;
mailMessage.From = new System.Net.Mail.MailAddress(mailItem.Sender.Address, mailItem.Sender.Name);
mailMessage.IsBodyHtml = mailItem.BodyFormat == OlBodyFormat.olFormatHTML;
mailMessage.Body = mailItem.BodyFormat == OlBodyFormat.olFormatHTML ? mailItem.HTMLBody : mailItem.Body;
foreach(Recipient recipient in mailItem.Recipients)
{
if(recipient.Type == (int)OlMailRecipientType.olTo)
{
mailMessage.To.Add(new System.Net.Mail.MailAddress(recipient.Address, recipient.Name));
}
else if(recipient.Type == (int)OlMailRecipientType.olCC)
{
mailMessage.CC.Add(new System.Net.Mail.MailAddress(recipient.Address, recipient.Name));
}
else if(recipient.Type == (int)OlMailRecipientType.olBCC)
{
mailMessage.Bcc.Add(new System.Net.Mail.MailAddress(recipient.Address, recipient.Name));
}
}
List<string> temporaryDirectoryPathList = new List<string>();
try
{
foreach(Attachment attachment in mailItem.Attachments)
{
#region 임시 디렉토리 경로를 설정한다.
string temporaryDirectoryPath = Path.Combine(Path.GetTempPath(), "Temp", Guid.NewGuid().ToString());
#endregion
#region 임시 디렉토리 경로를 생성한다.
if(!Directory.Exists(temporaryDirectoryPath))
{
Directory.CreateDirectory(temporaryDirectoryPath);
}
#endregion
temporaryDirectoryPathList.Add(temporaryDirectoryPath);
#region 첨부 파일을 저장한다.
string attachmentFilePath = Path.Combine(temporaryDirectoryPath, attachment.FileName);
attachment.SaveAsFile(attachmentFilePath);
#endregion
#region MIME 타입을 설정한다.
string fileExtension = Path.GetExtension(attachment.FileName);
string mimeType = MIMETypeHelper.GetMIMEType(fileExtension);
#endregion
mailMessage.Attachments.Add(new System.Net.Mail.Attachment(attachmentFilePath, mimeType));
}
MimeMessage mimeMessage = (MimeMessage)mailMessage;
mimeMessage.Date = mailItem.CreationTime;
mimeMessage.WriteTo(filePath);
mailMessage.Dispose();
}
finally
{
foreach(string path in temporaryDirectoryPathList)
{
if(Directory.Exists(path))
{
Directory.Delete(path, true);
}
}
}
}
#endregion
}
}
300x250
▶ CustomAddIn.cs
using Microsoft.Office.Core;
using System;
namespace TestProject
{
/// <summary>
/// 커스텀 애드인
/// </summary>
public partial class CustomAddIn
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Protected
#region 리본 확장성 객체 생성하기 - CreateRibbonExtensibilityObject()
/// <summary>
/// 리본 확장성 객체 생성하기
/// </summary>
/// <returns>리본 확장성 인터페이스 객체</returns>
protected override IRibbonExtensibility CreateRibbonExtensibilityObject()
{
return new RibbonContextMenu();
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 커스텀 애드인 시작시 처리하기 - CustomAddIn_Startup(sender, e)
/// <summary>
/// 커스텀 애드인 시작시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void CustomAddIn_Startup(object sender, EventArgs e)
{
}
#endregion
#region 커스텀 애드인 셧다운시 처리하기 - CustomAddIn_Shutdown(sender, e)
/// <summary>
/// 커스텀 애드인 셧다운시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void CustomAddIn_Shutdown(object sender, EventArgs e)
{
}
#endregion
#region VSTO에서 생성한 코드
/// <summary>
/// 디자이너 지원에 필요한 메서드입니다.
/// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
/// </summary>
private void InternalStartup()
{
this.Startup += new EventHandler(CustomAddIn_Startup );
this.Shutdown += new EventHandler(CustomAddIn_Shutdown);
}
#endregion
}
}
728x90
그리드형(광고전용)
'C# > Outlook' 카테고리의 다른 글
[C#/OUTLOOK] Application 인터페이스 : Version 속성을 사용해 아웃룩 버전 구하기 (0) | 2021.08.10 |
---|---|
[C#/OUTLOOK] 설치 디렉토리 경로 구하기 (0) | 2021.08.07 |
[C#/OUTLOOK] MailItem 인터페이스 : 메일 메시지 헤더 구하기 (0) | 2021.08.07 |
[C#/OUTLOOK] MAPIFolder 인터페이스 : 전체 폴더 경로를 사용해 폴더 구하기 (0) | 2021.08.07 |
[C#/OUTLOOK] ExplorerEvents_10_Event 인터페이스 : Close 이벤트를 사용해 프로그램 종료시 처리하기 (0) | 2021.08.07 |
[C#/OUTLOOK] NameSpace 인터페이스 : Accounts 속성/GetDefaultFolder 메소드를 사용해 메일 계정별 디폴트 폴더 구하기 (0) | 2021.08.06 |
[C#/OUTLOOK] Account 인터페이스 : Session 속성을 사용해 해당 메일 계정의 받은 편지함 폴더 구하기 (0) | 2021.08.06 |
[C#/OUTLOOK] NameSpace 인터페이스 : GetDefaultFolder 메소드를 사용해 디폴트 폴더 구하기 (0) | 2021.08.06 |
[C#/OUTLOOK] MAPIFolderEvents_12_Event 인터페이스 : BeforeFolderMove/BeforeItemMove 이벤트를 사용해 폴더/메일 삭제/이동 방지하기 (기능 개선) (0) | 2021.08.06 |
[C#/OUTLOOK] 폴더/메일 항목 사용자 속성 추가/조회/삭제하기 (0) | 2021.07.30 |