diff --git a/GreenshotOfficePlugin/GreenshotOfficePlugin.csproj b/GreenshotOfficePlugin/GreenshotOfficePlugin.csproj
index fa23955ce..bc7dfc6fa 100644
--- a/GreenshotOfficePlugin/GreenshotOfficePlugin.csproj
+++ b/GreenshotOfficePlugin/GreenshotOfficePlugin.csproj
@@ -57,42 +57,18 @@
-
- Interop\ExcelExporter.cs
-
-
- Interop\OneNoteExporter.cs
-
-
- Interop\OutlookEmailExporter.cs
-
-
- Interop\PowerpointExporter.cs
-
-
- Interop\WordExporter.cs
-
-
- Interop\ExcelInterop.cs
-
-
- Interop\OfficeInterop.cs
-
-
- Interop\OneNoteInterop.cs
-
-
- Interop\OutlookInterop.cs
-
-
- Interop\OutlookUtils.cs
-
-
- Interop\PowerpointInterop.cs
-
-
- Interop\WordInterop.cs
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/GreenshotOfficePlugin/OfficeExport/ExcelExporter.cs b/GreenshotOfficePlugin/OfficeExport/ExcelExporter.cs
new file mode 100644
index 000000000..d9e077df0
--- /dev/null
+++ b/GreenshotOfficePlugin/OfficeExport/ExcelExporter.cs
@@ -0,0 +1,88 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Reflection;
+
+using Greenshot.Interop;
+
+namespace Greenshot.Interop.Office {
+ public class ExcelExporter {
+ private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ExcelExporter));
+
+ public static List GetWorkbooks() {
+ List currentWorkbooks = new List();
+ using (IExcelApplication excelApplication = COMWrapper.GetInstance()) {
+ if (excelApplication != null) {
+ for (int i = 1; i <= excelApplication.Workbooks.Count; i++) {
+ IWorkbook workbook = excelApplication.Workbooks[i];
+ if (workbook != null) {
+ currentWorkbooks.Add(workbook.Name);
+ }
+ }
+ }
+ }
+ return currentWorkbooks;
+ }
+
+ ///
+ /// Insert image from supplied tmp file into the give excel workbook
+ ///
+ ///
+ ///
+ public static void InsertIntoExistingWorkbook(string workbookName, string tmpFile) {
+ using (IExcelApplication excelApplication = COMWrapper.GetInstance()) {
+ if (excelApplication != null) {
+ for (int i = 1; i <= excelApplication.Workbooks.Count; i++) {
+ IWorkbook workbook = excelApplication.Workbooks[i];
+ if (workbook != null && workbook.Name.StartsWith(workbookName)) {
+ InsertIntoExistingWorkbook(workbook, tmpFile);
+ }
+ }
+ }
+ }
+ }
+
+ private static void InsertIntoExistingWorkbook(IWorkbook workbook, string tmpFile) {
+ IWorksheet sheet = workbook.ActiveSheet;
+ if (sheet != null) {
+ if (sheet.Pictures != null) {
+ sheet.Pictures.Insert(tmpFile);
+ }
+ } else {
+ LOG.Error("No pictures found");
+ }
+ }
+
+ public static void InsertIntoNewWorkbook(string tmpFile) {
+ using (IExcelApplication excelApplication = COMWrapper.GetOrCreateInstance()) {
+ if (excelApplication != null) {
+ excelApplication.Visible = true;
+ object template = Missing.Value;
+ IWorkbook workbook = excelApplication.Workbooks.Add(template);
+ InsertIntoExistingWorkbook(workbook, tmpFile);
+ }
+ }
+ }
+ }
+
+}
diff --git a/GreenshotOfficePlugin/OfficeExport/OneNoteExporter.cs b/GreenshotOfficePlugin/OfficeExport/OneNoteExporter.cs
new file mode 100644
index 000000000..6a6f14e0e
--- /dev/null
+++ b/GreenshotOfficePlugin/OfficeExport/OneNoteExporter.cs
@@ -0,0 +1,100 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using Greenshot.Interop;
+using System.Reflection;
+using System.Xml;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using Greenshot.Plugin;
+using GreenshotPlugin.Core;
+
+namespace Greenshot.Interop.Office {
+ public class OneNotePage {
+ public string PageName { get; set; }
+ public string PageID { get; set; }
+ }
+ public class OneNoteExporter {
+ private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(OneNoteExporter));
+ private const string XML_IMAGE_CONTENT = "{0}";
+ private const string XML_OUTLINE = "{0}";
+ private const string ONENOTE_NAMESPACE_2007 = "http://schemas.microsoft.com/office/onenote/2007/onenote";
+ private const string ONENOTE_NAMESPACE_2010 = "http://schemas.microsoft.com/office/onenote/2010/onenote";
+
+ public static void ExportToPage(Bitmap imageToExport, OneNotePage page) {
+ using (MemoryStream pngStream = new MemoryStream()) {
+ OutputSettings pngOutputSettings = new OutputSettings(OutputFormat.png, 100, false);
+ ImageOutput.SaveToStream(imageToExport, pngStream, pngOutputSettings);
+ string base64String = Convert.ToBase64String(pngStream.GetBuffer());
+ string imageXmlStr = string.Format(XML_IMAGE_CONTENT, base64String, imageToExport.Width, imageToExport.Height);
+ string pageChangesXml = string.Format(XML_OUTLINE, new object[] { imageXmlStr, page.PageID, ONENOTE_NAMESPACE_2010, page.PageName });
+ using (IOneNoteApplication oneNoteApplication = COMWrapper.GetOrCreateInstance()) {
+ LOG.InfoFormat("Sending XML: {0}", pageChangesXml);
+ oneNoteApplication.UpdatePageContent(pageChangesXml, DateTime.MinValue, XMLSchema.xs2010, false);
+ }
+ }
+ }
+
+ ///
+ /// Get the captions of all the open word documents
+ ///
+ ///
+ public static List GetPages() {
+ List pages = new List();
+ try {
+ using (IOneNoteApplication oneNoteApplication = COMWrapper.GetOrCreateInstance()) {
+ if (oneNoteApplication != null) {
+ string notebookXml = "";
+ oneNoteApplication.GetHierarchy("", HierarchyScope.hsPages, out notebookXml, XMLSchema.xs2010);
+ if (!string.IsNullOrEmpty(notebookXml)) {
+ LOG.Debug(notebookXml);
+ using (StringReader reader = new StringReader(notebookXml)) {
+ using (XmlTextReader xmlReader = new XmlTextReader(reader)) {
+ while (xmlReader.Read()) {
+ if ("one:Page".Equals(xmlReader.Name)) {
+ if ("true".Equals(xmlReader.GetAttribute("isCurrentlyViewed"))) {
+ OneNotePage page = new OneNotePage();
+ page.PageName = xmlReader.GetAttribute("name");
+ page.PageID = xmlReader.GetAttribute("ID");
+ pages.Add(page);
+ // For debugging
+ //string pageXml = "";
+ //oneNoteApplication.GetPageContent(page.PageID, out pageXml, PageInfo.piAll, XMLSchema.xs2010);
+ //LOG.DebugFormat("Page XML: {0}", pageXml);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception ex) {
+ LOG.Warn("Problem retrieving onenote destinations, ignoring: ", ex);
+ }
+ return pages;
+ }
+ }
+}
diff --git a/GreenshotOfficePlugin/OfficeExport/OutlookEmailExporter.cs b/GreenshotOfficePlugin/OfficeExport/OutlookEmailExporter.cs
new file mode 100644
index 000000000..1004ea439
--- /dev/null
+++ b/GreenshotOfficePlugin/OfficeExport/OutlookEmailExporter.cs
@@ -0,0 +1,520 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+
+using Microsoft.Win32;
+
+using Greenshot.Interop;
+using Greenshot.Interop.IE;
+using System.Threading;
+
+namespace Greenshot.Interop.Office {
+ ///
+ /// Outlook exporter has all the functionality to export to outlook
+ ///
+ public class OutlookEmailExporter {
+ private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(OutlookEmailExporter));
+ private static readonly string SIGNATURE_PATH = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"Microsoft\Signatures");
+ private static Version outlookVersion = null;
+ private static string currentUser = null;
+ private const int OUTLOOK_2003 = 11;
+ private const int OUTLOOK_2007 = 12;
+ private const int OUTLOOK_2010 = 14;
+
+ // The signature key can be found at:
+ // HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\\9375CFF0413111d3B88A00104B2A6676\ [New Signature]
+ private const string PROFILES_KEY = @"Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\";
+ private const string ACCOUNT_KEY = "9375CFF0413111d3B88A00104B2A6676";
+ private const string NEW_SIGNATURE_VALUE = "New Signature";
+ private const string DEFAULT_PROFILE_VALUE = "DefaultProfile";
+
+ ///
+ /// A method to retrieve all inspectors which can act as an export target
+ ///
+ /// bool true if also exporting to meetings
+ /// List with inspector captions (window title)
+ public static Dictionary RetrievePossibleTargets(bool allowMeetingAsTarget) {
+ Dictionary inspectorCaptions = new Dictionary();
+ try {
+ using (IOutlookApplication outlookApplication = GetOutlookApplication()) {
+ if (outlookApplication == null) {
+ return null;
+ }
+
+ using (Inspectors inspectors = outlookApplication.Inspectors) {
+ if (inspectors != null && inspectors.Count > 0) {
+ for (int i = 1; i <= inspectors.Count; i++) {
+ using (Inspector inspector = outlookApplication.Inspectors[i]) {
+ string inspectorCaption = inspector.Caption;
+ using (Item currentItem = inspector.CurrentItem) {
+ if (canExportToInspector(currentItem, allowMeetingAsTarget)) {
+ OlObjectClass currentItemClass = currentItem.Class;
+ inspectorCaptions.Add(inspector.Caption, currentItemClass);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception ex) {
+ LOG.Warn("Problem retrieving word destinations, ignoring: ", ex);
+ }
+ return inspectorCaptions;
+ }
+
+ ///
+ /// Return true if we can export to the supplied inspector
+ ///
+ /// the Item to check
+ /// bool true if also exporting to meetings
+ ///
+ private static bool canExportToInspector(Item currentItem, bool allowMeetingAsTarget) {
+ try {
+ if (currentItem != null) {
+ OlObjectClass currentItemClass = currentItem.Class;
+ if (OlObjectClass.olMail.Equals(currentItemClass)) {
+ MailItem mailItem = (MailItem)currentItem;
+ //MailItem mailItem = COMWrapper.Cast(currentItem);
+ LOG.DebugFormat("Mail sent: {0}", mailItem.Sent);
+ if (!mailItem.Sent) {
+ return true;
+ }
+ } else if (outlookVersion.Major >= OUTLOOK_2010 && allowMeetingAsTarget && OlObjectClass.olAppointment.Equals(currentItemClass)) {
+ //AppointmentItem appointmentItem = COMWrapper.Cast(currentItem);
+ AppointmentItem appointmentItem = (AppointmentItem)currentItem;
+ if (string.IsNullOrEmpty(appointmentItem.Organizer) || (currentUser != null && currentUser.Equals(appointmentItem.Organizer))) {
+ return true;
+ } else {
+ LOG.DebugFormat("Not exporting, as organizer is {1} and currentuser {2}", appointmentItem.Organizer, currentUser);
+ }
+ }
+ }
+ } catch (Exception ex) {
+ LOG.WarnFormat("Couldn't process item due to: {0}", ex.Message);
+ }
+ return false;
+ }
+
+
+ ///
+ /// Export the image stored in tmpFile to the Inspector with the caption
+ ///
+ /// Caption of the inspector
+ /// Path to image file
+ /// name of the attachment (used as the tooltip of the image)
+ /// true if it worked
+ public static bool ExportToInspector(string inspectorCaption, string tmpFile, string attachmentName) {
+ // Assume true, although this might cause issues.
+ bool allowMeetingAsTarget = true;
+ using (IOutlookApplication outlookApplication = GetOrCreateOutlookApplication()) {
+ if (outlookApplication != null) {
+ Inspectors inspectors = outlookApplication.Inspectors;
+ if (inspectors != null && inspectors.Count > 0) {
+ LOG.DebugFormat("Got {0} inspectors to check", inspectors.Count);
+ for (int i = 1; i <= inspectors.Count; i++) {
+ using (Inspector inspector = outlookApplication.Inspectors[i]) {
+ string currentCaption = inspector.Caption;
+ if (currentCaption.StartsWith(inspectorCaption)) {
+ using (Item currentItem = inspector.CurrentItem) {
+ if (canExportToInspector(currentItem, allowMeetingAsTarget)) {
+ try {
+ return ExportToInspector(inspector, currentItem, tmpFile, attachmentName);
+ } catch (Exception exExport) {
+ LOG.Error("Export to " + currentCaption + " failed.", exExport);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ ///
+ /// Export the file to the supplied inspector
+ ///
+ /// Inspector
+ /// Item
+ ///
+ ///
+ ///
+ private static bool ExportToInspector(Inspector inspector, Item currentItem, string tmpFile, string attachmentName) {
+ if (currentItem == null) {
+ LOG.Warn("No current item.");
+ return false;
+ }
+ OlObjectClass itemClass = currentItem.Class;
+ bool isMail = OlObjectClass.olMail.Equals(itemClass);
+ bool isAppointment = OlObjectClass.olAppointment.Equals(itemClass);
+ if (!isMail && !isAppointment) {
+ LOG.Warn("Item is no mail or appointment.");
+ return false;
+ }
+ MailItem mailItem = null;
+ try {
+ if (isMail) {
+ //mailItem = COMWrapper.Cast(currentItem);
+ mailItem = (MailItem)currentItem;
+ if (mailItem.Sent) {
+ LOG.WarnFormat("Item already sent, can't export to {0}", currentItem.Subject);
+ return false;
+ }
+ }
+
+ // Make sure the inspector is activated, only this way the word editor is active!
+ // This also ensures that the window is visible!
+ inspector.Activate();
+ bool isTextFormat = OlBodyFormat.olFormatPlain.Equals(mailItem.BodyFormat);
+ if (isAppointment || !isTextFormat) {
+ // Check for wordmail, if so use the wordexporter
+ // http://msdn.microsoft.com/en-us/library/dd492012%28v=office.12%29.aspx
+ // Earlier versions of Outlook also supported an Inspector.HTMLEditor object property, but since Internet Explorer is no longer the rendering engine for HTML messages and posts, HTMLEditor is no longer supported.
+ if (inspector.IsWordMail() && inspector.WordEditor != null) {
+ try {
+ if (WordExporter.InsertIntoExistingDocument(inspector.WordEditor.Application, inspector.WordEditor, tmpFile)) {
+ LOG.Info("Inserted into Wordmail");
+
+ // check the format afterwards, otherwise we lose the selection
+ //if (!OlBodyFormat.olFormatHTML.Equals(currentMail.BodyFormat)) {
+ // LOG.Info("Changing format to HTML.");
+ // currentMail.BodyFormat = OlBodyFormat.olFormatHTML;
+ //}
+ return true;
+ }
+ } catch (Exception exportException) {
+ LOG.Error("Error exporting to the word editor, trying to do it via another method", exportException);
+ }
+ } else if (isAppointment) {
+ LOG.Info("Can't export to an appointment if no word editor is used");
+ return false;
+ } else {
+ LOG.Info("Trying export for outlook < 2007.");
+ }
+ }
+ // Only use mailitem as it should be filled!!
+ LOG.InfoFormat("Item '{0}' has format: {1}", mailItem.Subject, mailItem.BodyFormat);
+
+ string contentID;
+ if (outlookVersion.Major >= OUTLOOK_2007) {
+ contentID = Guid.NewGuid().ToString();
+ } else {
+ LOG.Info("Older Outlook (<2007) found, using filename as contentid.");
+ contentID = Path.GetFileName(tmpFile);
+ }
+
+ // Use this to change the format, it will probably lose the current selection.
+ //if (!OlBodyFormat.olFormatHTML.Equals(currentMail.BodyFormat)) {
+ // LOG.Info("Changing format to HTML.");
+ // currentMail.BodyFormat = OlBodyFormat.olFormatHTML;
+ //}
+
+ bool inlinePossible = false;
+ if (OlBodyFormat.olFormatHTML.Equals(mailItem.BodyFormat)) {
+ // if html we can try to inline it
+ // The following might cause a security popup... can't ignore it.
+ try {
+ IHTMLDocument2 document2 = inspector.HTMLEditor as IHTMLDocument2;
+ if (document2 != null) {
+ IHTMLSelectionObject selection = document2.selection;
+ if (selection != null) {
+ IHTMLTxtRange range = selection.createRange();
+ if (range != null) {
+ // First paste, than attach (otherwise the range is wrong!)
+ range.pasteHTML("

");
+ inlinePossible = true;
+ } else {
+ LOG.DebugFormat("No range for '{0}'", inspector.Caption);
+ }
+ } else {
+ LOG.DebugFormat("No selection for '{0}'", inspector.Caption);
+ }
+ } else {
+ LOG.DebugFormat("No HTML editor for '{0}'", inspector.Caption);
+ }
+ } catch (Exception e) {
+ // Continue with non inline image
+ LOG.Warn("Error pasting HTML, most likely due to an ACCESS_DENIED as the user clicked no.", e);
+ }
+ }
+
+ // Create the attachment (if inlined the attachment isn't visible as attachment!)
+ using (Attachment attachment = mailItem.Attachments.Add(tmpFile, OlAttachmentType.olByValue, inlinePossible ? 0 : 1, attachmentName)) {
+ if (outlookVersion.Major >= OUTLOOK_2007) {
+ // Add the content id to the attachment, this only works for Outlook >= 2007
+ try {
+ PropertyAccessor propertyAccessor = attachment.PropertyAccessor;
+ propertyAccessor.SetProperty(PropTag.ATTACHMENT_CONTENT_ID, contentID);
+ } catch {
+ }
+ }
+ }
+ } catch (Exception ex) {
+ LOG.WarnFormat("Problem while trying to add attachment to Item '{0}' : {1}", inspector.Caption, ex);
+ return false;
+ }
+ LOG.Debug("Finished!");
+ return true;
+ }
+ ///
+ /// Export image to a new email
+ ///
+ ///
+ ///
+ ///
+ private static void ExportToNewEmail(IOutlookApplication outlookApplication, EmailFormat format, string tmpFile, string subject, string attachmentName, string to, string CC, string BCC) {
+ Item newItem = outlookApplication.CreateItem(OlItemType.olMailItem);
+ if (newItem == null) {
+ return;
+ }
+ //MailItem newMail = COMWrapper.Cast(newItem);
+ MailItem newMail = (MailItem)newItem;
+ newMail.Subject = subject;
+ if (!string.IsNullOrEmpty(to)) {
+ newMail.To = to;
+ }
+ if (!string.IsNullOrEmpty(CC)) {
+ newMail.CC = CC;
+ }
+ if (!string.IsNullOrEmpty(BCC)) {
+ newMail.BCC = BCC;
+ }
+ newMail.BodyFormat = OlBodyFormat.olFormatHTML;
+ string bodyString = null;
+ // Read the default signature, if nothing found use empty email
+ try {
+ bodyString = GetOutlookSignature(format);
+ } catch (Exception e) {
+ LOG.Error("Problem reading signature!", e);
+ }
+ switch (format) {
+ case EmailFormat.Text:
+ newMail.Attachments.Add(tmpFile, OlAttachmentType.olByValue, 1, attachmentName);
+ newMail.BodyFormat = OlBodyFormat.olFormatPlain;
+ if (bodyString == null) {
+ bodyString = "";
+ }
+ newMail.Body = bodyString;
+ break;
+ case EmailFormat.HTML:
+ default:
+ string contentID = Path.GetFileName(tmpFile);
+ // Create the attachment
+ using (Attachment attachment = newMail.Attachments.Add(tmpFile, OlAttachmentType.olByValue, 0, attachmentName)) {
+ // add content ID to the attachment
+ if (outlookVersion.Major >= OUTLOOK_2007) {
+ try {
+ contentID = Guid.NewGuid().ToString();
+ PropertyAccessor propertyAccessor = attachment.PropertyAccessor;
+ propertyAccessor.SetProperty(PropTag.ATTACHMENT_CONTENT_ID, contentID);
+ } catch {
+ LOG.Info("Error working with the PropertyAccessor, using filename as contentid");
+ contentID = Path.GetFileName(tmpFile);
+ }
+ }
+ }
+
+ newMail.BodyFormat = OlBodyFormat.olFormatHTML;
+ string htmlImgEmbedded = "

";
+ string fallbackBody = "" + htmlImgEmbedded + "";
+ if (bodyString == null) {
+ bodyString = fallbackBody;
+ } else {
+ int bodyIndex = bodyString.IndexOf("= 0) {
+ bodyIndex = bodyString.IndexOf(">", bodyIndex) + 1;
+ if (bodyIndex >= 0) {
+ bodyString = bodyString.Insert(bodyIndex, htmlImgEmbedded);
+ } else {
+ bodyString = fallbackBody;
+ }
+ } else {
+ bodyString = fallbackBody;
+ }
+ }
+ newMail.HTMLBody = bodyString;
+ break;
+ }
+ // So not save, otherwise the email is always stored in Draft folder.. (newMail.Save();)
+ try {
+ newMail.Display(false);
+ newMail.GetInspector().Activate();
+ } catch (Exception ex) {
+ LOG.Warn("Problem displaying the new email, retrying to display it. Problem:", ex);
+ Thread retryDisplayEmail = new Thread(delegate() {
+ int retries = 10;
+ int retryInXSeconds = 5;
+ while (retries-- > 0) {
+ Thread.Sleep(retryInXSeconds * 1000);
+ try {
+ newMail.Display(false);
+ newMail.GetInspector().Activate();
+ LOG.InfoFormat("Managed to display the message.");
+ return;
+ } catch (Exception displayEx) {
+ LOG.WarnFormat("Error displaying message: {0}, retrying to show email in {1} seconds... Retries left: {2}", displayEx, retryInXSeconds, retries);
+ }
+ }
+ LOG.WarnFormat("Retry failed, saving message to draft.");
+ try {
+ newMail.Save();
+ } catch (Exception saveEx) {
+ LOG.WarnFormat("Saving message to draft failed: {0}", saveEx);
+ }
+ });
+ retryDisplayEmail.Name = "Retry to display email";
+ retryDisplayEmail.IsBackground = true;
+ retryDisplayEmail.Start();
+ }
+ if (newItem != null) {
+ newItem.Dispose();
+ }
+ }
+
+ ///
+ /// Helper method to create an outlook mail item with attachment
+ ///
+ /// The file to send, do not delete the file right away!
+ /// true if it worked, false if not
+ public static bool ExportToOutlook(EmailFormat format, string tmpFile, string subject, string attachmentName, string to, string CC, string BCC) {
+ bool exported = false;
+ try {
+ using (IOutlookApplication outlookApplication = GetOrCreateOutlookApplication()) {
+ if (outlookApplication != null) {
+ ExportToNewEmail(outlookApplication, format, tmpFile, subject, attachmentName, to, CC, BCC);
+ exported = true;
+ }
+ }
+ return exported;
+ } catch (Exception e) {
+ LOG.Error("Error while creating an outlook mail item: ", e);
+ }
+ return exported;
+ }
+
+ ///
+ /// Helper method to get the Outlook signature
+ ///
+ ///
+ private static string GetOutlookSignature(EmailFormat format) {
+ using (RegistryKey profilesKey = Registry.CurrentUser.OpenSubKey(PROFILES_KEY, false)) {
+ if (profilesKey == null) {
+ return null;
+ }
+ string defaultProfile = (string)profilesKey.GetValue(DEFAULT_PROFILE_VALUE);
+ LOG.DebugFormat("defaultProfile={0}", defaultProfile);
+ using (RegistryKey profileKey = profilesKey.OpenSubKey(defaultProfile + @"\" + ACCOUNT_KEY, false)) {
+ if (profilesKey == null) {
+ return null;
+ }
+ string[] numbers = profileKey.GetSubKeyNames();
+ foreach (string number in numbers) {
+ LOG.DebugFormat("Found subkey {0}", number);
+ using (RegistryKey numberKey = profileKey.OpenSubKey(number, false)) {
+ byte[] val = (byte[])numberKey.GetValue(NEW_SIGNATURE_VALUE);
+ if (val == null) {
+ continue;
+ }
+ string signatureName = "";
+ foreach (byte b in val) {
+ if (b != 0) {
+ signatureName += (char)b;
+ }
+ }
+ LOG.DebugFormat("Found email signature: {0}", signatureName);
+ string extension;
+ switch (format) {
+ case EmailFormat.Text:
+ extension = ".txt";
+ break;
+ case EmailFormat.HTML:
+ default:
+ extension = ".htm";
+ break;
+ }
+ string signatureFile = Path.Combine(SIGNATURE_PATH, signatureName + extension);
+ if (File.Exists(signatureFile)) {
+ LOG.DebugFormat("Found email signature file: {0}", signatureFile);
+ return File.ReadAllText(signatureFile, Encoding.Default);
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ ///
+ /// Initialize static outlook variables like version and currentuser
+ ///
+ ///
+ private static void InitializeVariables(IOutlookApplication outlookApplication) {
+ if (outlookApplication == null || outlookVersion != null) {
+ return;
+ }
+ try {
+ outlookVersion = new Version(outlookApplication.Version);
+ LOG.InfoFormat("Using Outlook {0}", outlookVersion);
+ } catch (Exception exVersion) {
+ LOG.Error(exVersion);
+ LOG.Warn("Assuming outlook version 1.");
+ outlookVersion = new Version(1, 1, 1, 1);
+ }
+ // Preventing retrieval of currentUser if Outlook is older than 2007
+ if (outlookVersion.Major >= OUTLOOK_2007) {
+ try {
+ INameSpace mapiNamespace = outlookApplication.GetNameSpace("MAPI");
+ currentUser = mapiNamespace.CurrentUser.Name;
+ LOG.InfoFormat("Current user: {0}", currentUser);
+ } catch (Exception exNS) {
+ LOG.Error(exNS);
+ }
+ }
+ }
+
+ ///
+ /// Call this to get the running outlook application, returns null if there isn't any.
+ ///
+ /// IOutlookApplication or null
+ private static IOutlookApplication GetOutlookApplication() {
+ IOutlookApplication outlookApplication = COMWrapper.GetInstance();
+ InitializeVariables(outlookApplication);
+ return outlookApplication;
+ }
+
+ ///
+ /// Call this to get the running outlook application, or create a new instance
+ ///
+ /// IOutlookApplication
+ private static IOutlookApplication GetOrCreateOutlookApplication() {
+ IOutlookApplication outlookApplication = COMWrapper.GetOrCreateInstance();
+ InitializeVariables(outlookApplication);
+ return outlookApplication;
+ }
+ }
+
+}
diff --git a/GreenshotOfficePlugin/OfficeExport/PowerpointExporter.cs b/GreenshotOfficePlugin/OfficeExport/PowerpointExporter.cs
new file mode 100644
index 000000000..f99a2a012
--- /dev/null
+++ b/GreenshotOfficePlugin/OfficeExport/PowerpointExporter.cs
@@ -0,0 +1,185 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Text;
+
+using Greenshot.Interop;
+
+namespace Greenshot.Interop.Office {
+ public class PowerpointExporter {
+ private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(PowerpointExporter));
+ private static string version = null;
+
+ public static bool isAfter2003() {
+ if (version != null) {
+ return !version.StartsWith("11");
+ }
+ return false;
+ }
+ ///
+ /// Get the captions of all the open powerpoint presentations
+ ///
+ ///
+ public static System.Collections.Generic.List GetPowerpointPresentations() {
+ System.Collections.Generic.List presentations = new System.Collections.Generic.List();
+ try {
+ using (IPowerpointApplication powerpointApplication = COMWrapper.GetInstance()) {
+ if (powerpointApplication != null) {
+ if (version == null) {
+ version = powerpointApplication.Version;
+ }
+ LOG.DebugFormat("Open Presentations: {0}", powerpointApplication.Presentations.Count);
+ for (int i = 1; i <= powerpointApplication.Presentations.Count; i++) {
+ IPresentation presentation = powerpointApplication.Presentations.item(i);
+ if (presentation != null && presentation.ReadOnly != MsoTriState.msoTrue) {
+ if (isAfter2003()) {
+ if (presentation.Final) {
+ continue;
+ }
+ }
+ presentations.Add(presentation.Name);
+ }
+ }
+ }
+ }
+ } catch (Exception ex) {
+ LOG.Warn("Problem retrieving word destinations, ignoring: ", ex);
+ }
+
+ return presentations;
+ }
+
+ ///
+ /// Export the image from the tmpfile to the presentation with the supplied name
+ ///
+ /// Name of the presentation to insert to
+ /// Filename of the image file to insert
+ /// Size of the image
+ /// A string with the image title
+ ///
+ public static bool ExportToPresentation(string presentationName, string tmpFile, Size imageSize, string title) {
+ using (IPowerpointApplication powerpointApplication = COMWrapper.GetInstance()) {
+ if (powerpointApplication != null) {
+ LOG.DebugFormat("Open Presentations: {0}", powerpointApplication.Presentations.Count);
+ for (int i = 1; i <= powerpointApplication.Presentations.Count; i++) {
+ IPresentation presentation = powerpointApplication.Presentations.item(i);
+ if (presentation != null && presentation.Name.StartsWith(presentationName)) {
+ try {
+ AddPictureToPresentation(presentation, tmpFile, imageSize, title);
+ return true;
+ } catch (Exception e) {
+ LOG.Error(e);
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private static void AddPictureToPresentation(IPresentation presentation, string tmpFile, Size imageSize, string title) {
+ if (presentation != null) {
+ //ISlide slide = presentation.Slides.AddSlide( presentation.Slides.Count + 1, PPSlideLayout.ppLayoutPictureWithCaption);
+ ISlide slide;
+ float left = (presentation.PageSetup.SlideWidth / 2) - (imageSize.Width / 2) ;
+ float top = (presentation.PageSetup.SlideHeight / 2) - (imageSize.Height / 2);
+ float width = imageSize.Width;
+ float height = imageSize.Height;
+ bool isLayoutPictureWithCaption = false;
+ IShape shapeForCaption = null;
+ bool hasScaledWidth = false;
+ bool hasScaledHeight = false;
+ try {
+ slide = presentation.Slides.Add(presentation.Slides.Count + 1, (int)PPSlideLayout.ppLayoutPictureWithCaption);
+ isLayoutPictureWithCaption = true;
+ // Shapes[2] is the image shape on this layout.
+ shapeForCaption = slide.Shapes.item(1);
+ IShape shapeForLocation = slide.Shapes.item(2);
+
+ if (width > shapeForLocation.Width) {
+ width = shapeForLocation.Width;
+ left = shapeForLocation.Left;
+ hasScaledWidth = true;
+ } else {
+ shapeForLocation.Left = left;
+ }
+ shapeForLocation.Width = imageSize.Width;
+
+ if (height > shapeForLocation.Height) {
+ height = shapeForLocation.Height;
+ top = shapeForLocation.Top;
+ hasScaledHeight = true;
+ } else {
+ top = (shapeForLocation.Top + (shapeForLocation.Height / 2)) - (imageSize.Height / 2);
+ }
+ shapeForLocation.Height = imageSize.Height;
+ } catch (Exception e) {
+ LOG.Error(e);
+ slide = presentation.Slides.Add(presentation.Slides.Count + 1, (int)PPSlideLayout.ppLayoutBlank);
+ }
+ IShape shape = slide.Shapes.AddPicture(tmpFile, MsoTriState.msoFalse, MsoTriState.msoTrue, 0, 0, width, height);
+ shape.LockAspectRatio = MsoTriState.msoTrue;
+ shape.ScaleHeight(1, MsoTriState.msoTrue, MsoScaleFrom.msoScaleFromMiddle);
+ shape.ScaleWidth(1, MsoTriState.msoTrue, MsoScaleFrom.msoScaleFromMiddle);
+ if (hasScaledWidth) {
+ shape.Width = width;
+ }
+ if (hasScaledHeight) {
+ shape.Height = height;
+ }
+ shape.Left = left;
+ shape.Top = top;
+ shape.AlternativeText = title;
+ if (isLayoutPictureWithCaption && shapeForCaption != null) {
+ try {
+ // Using try/catch to make sure problems with the text range don't give an exception.
+ ITextFrame textFrame = shapeForCaption.TextFrame;
+ textFrame.TextRange.Text = title;
+ } catch (Exception ex) {
+ LOG.Warn("Problem setting the title to a text-range", ex);
+ }
+ }
+ presentation.Application.ActiveWindow.View.GotoSlide(slide.SlideNumber);
+ presentation.Application.Activate();
+ }
+ }
+
+ public static bool InsertIntoNewPresentation(string tmpFile, Size imageSize, string title) {
+ bool isPictureAdded = false;
+ using (IPowerpointApplication powerpointApplication = COMWrapper.GetOrCreateInstance()) {
+ if (powerpointApplication != null) {
+ powerpointApplication.Visible = true;
+ IPresentation presentation = powerpointApplication.Presentations.Add(MsoTriState.msoTrue);
+ try {
+ AddPictureToPresentation(presentation, tmpFile, imageSize, title);
+ isPictureAdded = true;
+ presentation.Application.Activate();
+ } catch (Exception e) {
+ LOG.Error(e);
+ }
+ }
+ }
+ return isPictureAdded;
+ }
+ }
+}
diff --git a/GreenshotOfficePlugin/OfficeExport/WordExporter.cs b/GreenshotOfficePlugin/OfficeExport/WordExporter.cs
new file mode 100644
index 000000000..ed22f0221
--- /dev/null
+++ b/GreenshotOfficePlugin/OfficeExport/WordExporter.cs
@@ -0,0 +1,148 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using Greenshot.Interop;
+
+namespace Greenshot.Interop.Office {
+ public class WordExporter {
+ private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(WordExporter));
+ private static string version = null;
+
+ public static bool isAfter2003() {
+ if (version != null) {
+ return !version.StartsWith("11");
+ }
+ return false;
+ }
+ ///
+ /// Insert the bitmap stored under the tempfile path into the word document with the supplied caption
+ ///
+ ///
+ ///
+ ///
+ public static bool InsertIntoExistingDocument(string wordCaption, string tmpFile) {
+ using (IWordApplication wordApplication = COMWrapper.GetInstance()) {
+ if (wordApplication != null) {
+ for (int i = 1; i <= wordApplication.Documents.Count; i++) {
+ using (IWordDocument wordDocument = wordApplication.Documents.item(i)) {
+ if (wordDocument.ActiveWindow.Caption.StartsWith(wordCaption)) {
+ return InsertIntoExistingDocument(wordApplication, wordDocument, tmpFile);
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ ///
+ /// Internal method for the insert
+ ///
+ ///
+ ///
+ ///
+ ///
+ internal static bool InsertIntoExistingDocument(IWordApplication wordApplication, IWordDocument wordDocument, string tmpFile) {
+ if (wordApplication.Selection != null) {
+ AddPictureToSelection(wordApplication.Selection, tmpFile);
+ try {
+ wordDocument.ActiveWindow.ActivePane.View.Zoom.Percentage = 100;
+ } catch (Exception e) {
+ if (e.InnerException != null) {
+ LOG.WarnFormat("Couldn't set zoom to 100, error: {0}", e.InnerException.Message);
+ } else {
+ LOG.WarnFormat("Couldn't set zoom to 100, error: {0}", e.Message);
+ }
+ }
+ try {
+ wordApplication.Activate();
+ } catch {}
+ try {
+ wordDocument.Activate();
+ } catch {}
+ try {
+ wordDocument.ActiveWindow.Activate();
+ } catch {}
+ return true;
+ }
+ return false;
+ }
+
+ private static void AddPictureToSelection(ISelection selection, string tmpFile) {
+ selection.InlineShapes.AddPicture(tmpFile, false, true, Type.Missing);
+ selection.InsertAfter("\r\n");
+ }
+
+ public static void InsertIntoNewDocument(string tmpFile) {
+ using (IWordApplication wordApplication = COMWrapper.GetOrCreateInstance()) {
+ if (wordApplication != null) {
+ wordApplication.Visible = true;
+ wordApplication.Activate();
+ // Create new Document
+ object template = string.Empty;
+ object newTemplate = false;
+ object documentType = 0;
+ object documentVisible = true;
+ IWordDocument wordDocument = wordApplication.Documents.Add(ref template, ref newTemplate, ref documentType, ref documentVisible);
+ // Add Picture
+ AddPictureToSelection(wordApplication.Selection, tmpFile);
+ wordDocument.Activate();
+ wordDocument.ActiveWindow.Activate();
+ }
+ }
+ }
+
+ ///
+ /// Get the captions of all the open word documents
+ ///
+ ///
+ public static List GetWordDocuments() {
+ List documents = new List();
+ try {
+ using (IWordApplication wordApplication = COMWrapper.GetInstance()) {
+ if (wordApplication != null) {
+ if (version == null) {
+ version = wordApplication.Version;
+ }
+ for (int i = 1; i <= wordApplication.Documents.Count; i++) {
+ IWordDocument document = wordApplication.Documents.item(i);
+ if (document.ReadOnly) {
+ continue;
+ }
+ if (isAfter2003()) {
+ if (document.Final) {
+ continue;
+ }
+ }
+ documents.Add(document.ActiveWindow.Caption);
+ }
+ }
+ }
+ } catch (Exception ex) {
+ LOG.Warn("Problem retrieving word destinations, ignoring: ", ex);
+ }
+ return documents;
+ }
+ }
+}
diff --git a/GreenshotOfficePlugin/OfficeInterop/ExcelInterop.cs b/GreenshotOfficePlugin/OfficeInterop/ExcelInterop.cs
new file mode 100644
index 000000000..4134d1952
--- /dev/null
+++ b/GreenshotOfficePlugin/OfficeInterop/ExcelInterop.cs
@@ -0,0 +1,64 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+namespace Greenshot.Interop.Office {
+ // See http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.application.aspx
+ [ComProgId("Excel.Application")]
+ public interface IExcelApplication : Common {
+ IWorkbook ActiveWorkbook { get; }
+ //ISelection Selection {get;}
+ IWorkbooks Workbooks { get; }
+ bool Visible { get; set; }
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.workbooks.aspx
+ public interface IWorkbooks : Common, Collection {
+ IWorkbook Add(object template);
+ // Use index + 1!!
+ IWorkbook this[object Index] { get; }
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.workbook.aspx
+ public interface IWorkbook : Common {
+ IWorksheet ActiveSheet { get; }
+ string Name { get; }
+ void Activate();
+ IWorksheets Worksheets { get; }
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel._worksheet_members.aspx
+ public interface IWorksheet : Common {
+ IPictures Pictures { get; }
+ string Name { get; }
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.iworksheets_members.aspx
+ public interface IWorksheets : Common, Collection {
+ // Use index + 1!!
+ IWorksheet this[object Index] { get; }
+ }
+
+ public interface IPictures : Common, Collection {
+ // Use index + 1!!
+ //IPicture this[object Index] { get; }
+ void Insert(string file);
+ }
+}
diff --git a/GreenshotOfficePlugin/OfficeInterop/OfficeCommunicator.cs b/GreenshotOfficePlugin/OfficeInterop/OfficeCommunicator.cs
new file mode 100644
index 000000000..f659d12b3
--- /dev/null
+++ b/GreenshotOfficePlugin/OfficeInterop/OfficeCommunicator.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Greenshot.Interop;
+using Greenshot.Interop.Office;
+
+namespace GreenshotInterop.OfficeInterop {
+ // See: http://msdn.microsoft.com/en-us/library/bb758788%28v=office.12%29
+ [ComProgId("Communicator.UIAutomation")]
+ public interface IMessenger : Common {
+ void AutoSignin();
+ string MyServiceId {
+ get;
+ }
+ IMessengerContact GetContact(string signinName, string serviceId);
+ IMessengerWindow InstantMessage(string contact);
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/bb787250%28v=office.12%29
+ public interface IMessengerContact : Common {
+ string FriendlyName {
+ get;
+ }
+ string ServiceName {
+ get;
+ }
+ string ServiceId {
+ get;
+ }
+ string SigninName {
+ get;
+ }
+ MISTATUS Status {
+ get;
+ }
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/bb787207%28v=office.12%29
+ public enum MISTATUS {
+ MISTATUS_UNKNOWN = 0x0000,
+ MISTATUS_OFFLINE = 0x0001,
+ MISTATUS_ONLINE = 0x0002,
+ MISTATUS_INVISIBLE = 0x0006,
+ MISTATUS_BUSY = 0x000A,
+ MISTATUS_BE_RIGHT_BACK = 0x000E,
+ MISTATUS_IDLE = 0x0012,
+ MISTATUS_AWAY = 0x0022,
+ MISTATUS_ON_THE_PHONE = 0x0032,
+ MISTATUS_OUT_TO_LUNCH = 0x0042,
+ MISTATUS_IN_A_MEETING = 0x0052,
+ MISTATUS_OUT_OF_OFFICE = 0x0062,
+ MISTATUS_DO_NOT_DISTURB = 0x0072,
+ MISTATUS_IN_A_CONFERENCE = 0x0082,
+ MISTATUS_ALLOW_URGENT_INTERRUPTIONS = 0x0092,
+ MISTATUS_MAY_BE_AVAILABLE = 0x00A2,
+ MISTATUS_CUSTOM = 0x00B2,
+ MISTATUS_LOCAL_FINDING_SERVER = 0x0100,
+ MISTATUS_LOCAL_CONNECTING_TO_SERVER = 0x0200,
+ MISTATUS_LOCAL_SYNCHRONIZING_WITH_SERVER = 0x0300,
+ MISTATUS_LOCAL_DISCONNECTING_FROM_SERVER = 0x0400
+ } ;
+
+ // See: http://msdn.microsoft.com/en-us/library/bb758816%28v=office.12%29
+ public interface IMessengerWindow : Common {
+ bool IsClosed {
+ get;
+ }
+ void Show();
+ }
+
+}
diff --git a/GreenshotOfficePlugin/OfficeInterop/OfficeInterop.cs b/GreenshotOfficePlugin/OfficeInterop/OfficeInterop.cs
new file mode 100644
index 000000000..b69ca3045
--- /dev/null
+++ b/GreenshotOfficePlugin/OfficeInterop/OfficeInterop.cs
@@ -0,0 +1,31 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+using System.Collections;
+
+namespace Greenshot.Interop.Office {
+ ///
+ /// If the "type" this[object index] { get; } is implemented, use index + 1!!! (starts at 1)
+ ///
+ public interface Collection : Common, IEnumerable {
+ int Count { get; }
+ void Remove(int index);
+ }
+}
diff --git a/GreenshotOfficePlugin/OfficeInterop/OneNoteInterop.cs b/GreenshotOfficePlugin/OfficeInterop/OneNoteInterop.cs
new file mode 100644
index 000000000..9b3d1ad91
--- /dev/null
+++ b/GreenshotOfficePlugin/OfficeInterop/OneNoteInterop.cs
@@ -0,0 +1,59 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+using System;
+
+namespace Greenshot.Interop.Office {
+ // More details about OneNote: http://msdn.microsoft.com/en-us/magazine/ff796230.aspx
+
+ // See http://msdn.microsoft.com/de-de/library/microsoft.office.interop.word.applicationclass_members%28v=Office.11%29.aspx
+ [ComProgId("OneNote.Application")]
+ public interface IOneNoteApplication : Common {
+ ///
+ /// Make sure that the notebookXml is of type string, e.g. "", otherwise a type error occurs.
+ /// For more info on the methods: http://msdn.microsoft.com/en-us/library/gg649853.aspx
+ ///
+ void GetHierarchy(string startNode, HierarchyScope scope, out string notebookXml, XMLSchema schema);
+ void UpdatePageContent(string pageChangesXml, DateTime dateExpectedLastModified, XMLSchema schema, bool force);
+ void GetPageContent(string pageId, out string pageXml, PageInfo pageInfoToExport, XMLSchema schema);
+ }
+
+ public enum PageInfo {
+ piBasic = 0, // Returns only basic page content, without selection markup and binary data objects. This is the standard value to pass.
+ piBinaryData = 1, // Returns page content with no selection markup, but with all binary data.
+ piSelection = 2, // Returns page content with selection markup, but no binary data.
+ piBinaryDataSelection = 3, // Returns page content with selection markup and all binary data.
+ piAll = 3 // Returns all page content.
+ }
+
+ public enum HierarchyScope {
+ hsSelf = 0, // Gets just the start node specified and no descendants.
+ hsChildren = 1, //Gets the immediate child nodes of the start node, and no descendants in higher or lower subsection groups.
+ hsNotebooks = 2, // Gets all notebooks below the start node, or root.
+ hsSections = 3, //Gets all sections below the start node, including sections in section groups and subsection groups.
+ hsPages = 4 //Gets all pages below the start node, including all pages in section groups and subsection groups.
+ }
+
+ public enum XMLSchema {
+ xs2007 = 0,
+ xs2010 = 1,
+ xsCurrent= xs2010
+ }
+}
diff --git a/GreenshotOfficePlugin/OfficeInterop/OutlookInterop.cs b/GreenshotOfficePlugin/OfficeInterop/OutlookInterop.cs
new file mode 100644
index 000000000..fc33fb0a5
--- /dev/null
+++ b/GreenshotOfficePlugin/OfficeInterop/OutlookInterop.cs
@@ -0,0 +1,465 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+using System;
+using System.Collections;
+
+///
+/// This utils class should help setting the content-id on the attachment for Outlook < 2007
+/// But this somehow doesn't work yet
+///
+namespace Greenshot.Interop.Office {
+ ///
+ /// See: http://msdn.microsoft.com/en-us/library/bb208387%28v=office.12%29.aspx
+ ///
+ public interface Items : Collection, IEnumerable {
+ Item this[object index] { get; }
+ Item GetFirst();
+ Item GetNext();
+ Item GetLast();
+ Item GetPrevious();
+
+ bool IncludeRecurrences {
+ get;
+ set;
+ }
+
+ Items Restrict(string filter);
+ void Sort(string property, object descending);
+
+ // Actual definition is "object Add( object )", just making it convenient
+ object Add(OlItemType type);
+ }
+
+ // Common attributes of all the Items (MailItem, AppointmentItem)
+ // See: http://msdn.microsoft.com/en-us/library/ff861252.aspx
+ public interface Item : Common {
+ Attachments Attachments { get; }
+ string Body { get; set; }
+ OlObjectClass Class { get; }
+ DateTime CreationTime { get; }
+ string EntryID { get; }
+ DateTime LastModificationTime { get; }
+ string MessageClass { get; set; }
+ bool NoAging { get; set; }
+ int OutlookInternalVersion { get; }
+ string OutlookVersion { get; }
+ bool Saved { get; }
+ OlSensitivity Sensitivity { get; set; }
+ int Size { get; }
+ string Subject { get; set; }
+ bool UnRead { get; set; }
+ object Copy();
+ void Display(bool Modal);
+ void Save();
+ PropertyAccessor PropertyAccessor { get; }
+ Inspector GetInspector();
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/ff861252.aspx
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.mailitem.aspx
+ public interface MailItem : Item, Common {
+ bool Sent { get; }
+ object MAPIOBJECT { get; }
+ string HTMLBody { get; set; }
+ DateTime ExpiryTime { get; set; }
+ DateTime ReceivedTime { get; }
+ string SenderName { get; }
+ DateTime SentOn { get; }
+ OlBodyFormat BodyFormat { get; set; }
+ string To { get; set; }
+ string CC { get; set; }
+ string BCC { get; set; }
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/ff869026.aspx
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.appointmentitem.aspx
+ public interface AppointmentItem : Item, Common {
+ string Organizer { get; set; }
+ string SendUsingAccount { get; }
+ string Categories { get; }
+ DateTime Start { get; }
+ DateTime End { get; }
+ OlReoccurenceState RecurrenceState { get; }
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.contactitem.aspx
+ public interface ContactItem : Item, Common {
+ bool HasPicture {
+ get;
+ }
+ void SaveBusinessCardImage(string path);
+ void AddPicture(string path);
+ void RemovePicture();
+ string FirstName {
+ get;
+ set;
+ }
+ string LastName {
+ get;
+ set;
+ }
+ }
+
+ public interface Attachments : Collection {
+ Attachment Add(object source, object type, object position, object displayName);
+ // Use index+1!!!!
+ Attachment this[object index] { get; }
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.attachment_members.aspx
+ public interface Attachment : Common {
+ string DisplayName { get; set; }
+ string FileName { get; }
+ OlAttachmentType Type { get; }
+ PropertyAccessor PropertyAccessor { get; }
+ object MAPIOBJECT { get; }
+ void SaveAsFile(string path);
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.propertyaccessor_members.aspx
+ public interface PropertyAccessor : Common {
+ void SetProperty(string SchemaName, Object Value);
+ Object GetProperty(string SchemaName);
+ }
+
+ // Schema definitions for the MAPI properties
+ // See: http://msdn.microsoft.com/en-us/library/aa454438.aspx
+ // and see: http://msdn.microsoft.com/en-us/library/bb446117.aspx
+ public static class PropTag {
+ public const string ATTACHMENT_CONTENT_ID = @"http://schemas.microsoft.com/mapi/proptag/0x3712001E";
+ }
+ ///
+ /// Wrapper for Outlook.Application, see: http://msdn.microsoft.com/en-us/library/aa210897%28v=office.11%29.aspx
+ ///
+ [ComProgId("Outlook.Application")]
+ public interface IOutlookApplication : Common {
+ string Name { get; }
+ string Version { get; }
+ Item CreateItem(OlItemType ItemType);
+ object CreateItemFromTemplate(string TemplatePath, object InFolder);
+ object CreateObject(string ObjectName);
+ Inspector ActiveInspector();
+ Inspectors Inspectors { get; }
+ INameSpace GetNameSpace(string type);
+ }
+
+ ///
+ /// See: http://msdn.microsoft.com/en-us/library/bb176693%28v=office.12%29.aspx
+ ///
+ public interface INameSpace : Common {
+ IRecipient CurrentUser { get; }
+ IFolder GetDefaultFolder(OlDefaultFolders defaultFolder);
+ }
+
+ ///
+ /// See: http://msdn.microsoft.com/en-us/library/bb176362%28v=office.12%29.aspx
+ ///
+ public interface IFolder : Common {
+ Items Items {get;}
+ }
+
+ public interface IRecipient : Common {
+ string Name { get; }
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.inspector_members.aspx
+ public interface Inspector : Common {
+ Item CurrentItem { get; }
+ OlEditorType EditorType { get; }
+ object ModifiedFormPages { get; }
+ void Close(OlInspectorClose SaveMode);
+ void Display(object Modal);
+ void HideFormPage(string PageName);
+ bool IsWordMail();
+ void SetCurrentFormPage(string PageName);
+ void ShowFormPage(string PageName);
+ object HTMLEditor { get; }
+ IWordDocument WordEditor { get; }
+ string Caption { get; }
+ int Height { get; set; }
+ int Left { get; set; }
+ int Top { get; set; }
+ int Width { get; set; }
+ OlWindowState WindowState { get; set; }
+ void Activate();
+ void SetControlItemProperty(object Control, string PropertyName);
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook._application.inspectors.aspx
+ public interface Inspectors : Common, Collection, IEnumerable {
+ // Use index + 1!!
+ Inspector this[Object Index] { get; }
+ }
+
+ ///
+ /// Specifies which EmailFormat the email needs to use
+ ///
+ public enum EmailFormat {
+ Text, HTML
+ }
+ public enum OlBodyFormat {
+ // Fields
+ olFormatHTML = 2,
+ olFormatPlain = 1,
+ olFormatRichText = 3,
+ olFormatUnspecified = 0
+ }
+
+ public enum OlAttachmentType {
+ // Fields
+ olByReference = 4,
+ olByValue = 1,
+ olEmbeddeditem = 5,
+ olOLE = 6
+ }
+
+ public enum OlSensitivity {
+ // Fields
+ olConfidential = 3,
+ olNormal = 0,
+ olPersonal = 1,
+ olPrivate = 2
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/ff863329.aspx
+ public enum OlObjectClass {
+ olAccount = 105, // Represents an Account object.
+ olAccountRuleCondition = 135, // Represents an AccountRuleCondition object.
+ olAccounts = 106, // Represents an Accounts object.
+ olAction = 32, // Represents an Action object.
+ olActions = 33, // Represents an Actions object.
+ olAddressEntries = 21, // Represents an AddressEntries object.
+ olAddressEntry = 8, // Represents an AddressEntry object.
+ olAddressList = 7, // Represents an AddressList object.
+ olAddressLists = 20, // Represents an AddressLists object.
+ olAddressRuleCondition = 170, // Represents an AddressRuleCondition object.
+ olApplication = 0, // Represents an Application object.
+ olAppointment = 26, // Represents an AppointmentItem object.
+ olAssignToCategoryRuleAction = 122, // Represents an AssignToCategoryRuleAction object.
+ olAttachment = 5, // Represents an Attachment object.
+ olAttachments = 18, // Represents an Attachments object.
+ olAttachmentSelection = 169, // Represents an AttachmentSelection object.
+ olAutoFormatRule = 147, // Represents an AutoFormatRule object.
+ olAutoFormatRules = 148, // Represents an AutoFormatRules object.
+ olCalendarModule = 159, // Represents a CalendarModule object.
+ olCalendarSharing = 151, // Represents a CalendarSharing object.
+ olCategories = 153, // Represents a Categories object.
+ olCategory = 152, // Represents a Category object.
+ olCategoryRuleCondition = 130, // Represents a CategoryRuleCondition object.
+ olClassBusinessCardView = 168, // Represents a BusinessCardView object.
+ olClassCalendarView = 139, // Represents a CalendarView object.
+ olClassCardView = 138, // Represents a CardView object.
+ olClassIconView = 137, // Represents a IconView object.
+ olClassNavigationPane = 155, // Represents a NavigationPane object.
+ olClassTableView = 136, // Represents a TableView object.
+ olClassTimeLineView = 140, // Represents a TimelineView object.
+ olClassTimeZone = 174, // Represents a TimeZone object.
+ olClassTimeZones = 175, // Represents a TimeZones object.
+ olColumn = 154, // Represents a Column object.
+ olColumnFormat = 149, // Represents a ColumnFormat object.
+ olColumns = 150, // Represents a Columns object.
+ olConflict = 102, // Represents a Conflict object.
+ olConflicts = 103, // Represents a Conflicts object.
+ olContact = 40, // Represents a ContactItem object.
+ olContactsModule = 160, // Represents a ContactsModule object.
+ olDistributionList = 69, // Represents a ExchangeDistributionList object.
+ olDocument = 41, // Represents a DocumentItem object.
+ olException = 30, // Represents an Exception object.
+ olExceptions = 29, // Represents an Exceptions object.
+ olExchangeDistributionList = 111, // Represents an ExchangeDistributionList object.
+ olExchangeUser = 110, // Represents an ExchangeUser object.
+ olExplorer = 34, // Represents an Explorer object.
+ olExplorers = 60, // Represents an Explorers object.
+ olFolder = 2, // Represents a Folder object.
+ olFolders = 15, // Represents a Folders object.
+ olFolderUserProperties = 172, // Represents a UserDefinedProperties object.
+ olFolderUserProperty = 171, // Represents a UserDefinedProperty object.
+ olFormDescription = 37, // Represents a FormDescription object.
+ olFormNameRuleCondition = 131, // Represents a FormNameRuleCondition object.
+ olFormRegion = 129, // Represents a FormRegion object.
+ olFromRssFeedRuleCondition = 173, // Represents a FromRssFeedRuleCondition object.
+ olFromRuleCondition = 132, // Represents a ToOrFromRuleCondition object.
+ olImportanceRuleCondition = 128, // Represents an ImportanceRuleCondition object.
+ olInspector = 35, // Represents an Inspector object.
+ olInspectors = 61, // Represents an Inspectors object.
+ olItemProperties = 98, // Represents an ItemProperties object.
+ olItemProperty = 99, // Represents an ItemProperty object.
+ olItems = 16, // Represents an Items object.
+ olJournal = 42, // Represents a JournalItem object.
+ olJournalModule = 162, // Represents a JournalModule object.
+ olLink = 75, // Represents a Link object.
+ olLinks = 76, // Represents a Links object.
+ olMail = 43, // Represents a MailItem object.
+ olMailModule = 158, // Represents a MailModule object.
+ olMarkAsTaskRuleAction = 124, // Represents a MarkAsTaskRuleAction object.
+ olMeetingCancellation = 54, // Represents a MeetingItem object that is a meeting cancellation notice.
+ olMeetingRequest = 53, // Represents a MeetingItem object that is a meeting request.
+ olMeetingResponseNegative = 55, // Represents a MeetingItem object that is a refusal of a meeting request.
+ olMeetingResponsePositive = 56, // Represents a MeetingItem object that is an acceptance of a meeting request.
+ olMeetingResponseTentative = 57, // Represents a MeetingItem object that is a tentative acceptance of a meeting request.
+ olMoveOrCopyRuleAction = 118, // Represents a MoveOrCopyRuleAction object.
+ olNamespace = 1, // Represents a NameSpace object.
+ olNavigationFolder = 167, // Represents a NavigationFolder object.
+ olNavigationFolders = 166, // Represents a NavigationFolders object.
+ olNavigationGroup = 165, // Represents a NavigationGroup object.
+ olNavigationGroups = 164, // Represents a NavigationGroups object.
+ olNavigationModule = 157, // Represents a NavigationModule object.
+ olNavigationModules = 156, // Represents a NavigationModules object.
+ olNewItemAlertRuleAction = 125, // Represents a NewItemAlertRuleAction object.
+ olNote = 44, // Represents a NoteItem object.
+ olNotesModule = 163, // Represents a NotesModule object.
+ olOrderField = 144, // Represents an OrderField object.
+ olOrderFields = 145, // Represents an OrderFields object.
+ olOutlookBarGroup = 66, // Represents an OutlookBarGroup object.
+ olOutlookBarGroups = 65, // Represents an OutlookBarGroups object.
+ olOutlookBarPane = 63, // Represents an OutlookBarPane object.
+ olOutlookBarShortcut = 68, // Represents an OutlookBarShortcut object.
+ olOutlookBarShortcuts = 67, // Represents an OutlookBarShortcuts object.
+ olOutlookBarStorage = 64, // Represents an OutlookBarStorage object.
+ olPages = 36, // Represents a Pages object.
+ olPanes = 62, // Represents a Panes object.
+ olPlaySoundRuleAction = 123, // Represents a PlaySoundRuleAction object.
+ olPost = 45, // Represents a PostItem object.
+ olPropertyAccessor = 112, // Represents a PropertyAccessor object.
+ olPropertyPages = 71, // Represents a PropertyPages object.
+ olPropertyPageSite = 70, // Represents a PropertyPageSite object.
+ olRecipient = 4, // Represents a Recipient object.
+ olRecipients = 17, // Represents a Recipients object.
+ olRecurrencePattern = 28, // Represents a RecurrencePattern object.
+ olReminder = 101, // Represents a Reminder object.
+ olReminders = 100, // Represents a Reminders object.
+ olRemote = 47, // Represents a RemoteItem object.
+ olReport = 46, // Represents a ReportItem object.
+ olResults = 78, // Represents a Results object.
+ olRow = 121, // Represents a Row object.
+ olRule = 115, // Represents a Rule object.
+ olRuleAction = 117, // Represents a RuleAction object.
+ olRuleActions = 116, // Represents a RuleAction object.
+ olRuleCondition = 127, // Represents a RuleCondition object.
+ olRuleConditions = 126, // Represents a RuleConditions object.
+ olRules = 114, // Represents a Rules object.
+ olSearch = 77, // Represents a Search object.
+ olSelection = 74, // Represents a Selection object.
+ olSelectNamesDialog = 109, // Represents a SelectNamesDialog object.
+ olSenderInAddressListRuleCondition = 133, // Represents a SenderInAddressListRuleCondition object.
+ olSendRuleAction = 119, // Represents a SendRuleAction object.
+ olSharing = 104, // Represents a SharingItem object.
+ olStorageItem = 113, // Represents a StorageItem object.
+ olStore = 107, // Represents a Store object.
+ olStores = 108, // Represents a Stores object.
+ olSyncObject = 72, // Represents a SyncObject object.
+ olSyncObjects = 73, // Represents a SyncObject object.
+ olTable = 120, // Represents a Table object.
+ olTask = 48, // Represents a TaskItem object.
+ olTaskRequest = 49, // Represents a TaskRequestItem object.
+ olTaskRequestAccept = 51, // Represents a TaskRequestAcceptItem object.
+ olTaskRequestDecline = 52, // Represents a TaskRequestDeclineItem object.
+ olTaskRequestUpdate = 50, // Represents a TaskRequestUpdateItem object.
+ olTasksModule = 161, // Represents a TasksModule object.
+ olTextRuleCondition = 134, // Represents a TextRuleCondition object.
+ olUserDefinedProperties = 172, // Represents a UserDefinedProperties object.
+ olUserDefinedProperty = 171, // Represents a UserDefinedProperty object.
+ olUserProperties = 38, // Represents a UserProperties object.
+ olUserProperty = 39, // Represents a UserProperty object.
+ olView = 80, // Represents a View object.
+ olViewField = 142, // Represents a ViewField object.
+ olViewFields = 141, // Represents a ViewFields object.
+ olViewFont = 146, // Represents a ViewFont object.
+ olViews = 79 // Represents a Views object.
+ }
+
+ public enum OlDefaultFolders {
+ olFolderCalendar = 9, // The Calendar folder.
+ olFolderConflicts = 19, // The Conflicts folder (subfolder of Sync Issues folder). Only available for an Exchange account.
+ olFolderContacts = 10, // The Contacts folder.
+ olFolderDeletedItems = 3, // The Deleted Items folder.
+ olFolderDrafts = 16, // The Drafts folder.
+ olFolderInbox = 6, // The Inbox folder.
+ olFolderJournal = 11, // The Journal folder.
+ olFolderJunk = 23, // The Junk E-Mail folder.
+ olFolderLocalFailures = 21, // The Local Failures folder (subfolder of Sync Issues folder). Only available for an Exchange account.
+ olFolderManagedEmail = 29, // The top-level folder in the Managed Folders group. For more information on Managed Folders, see Help in Microsoft Outlook. Only available for an Exchange account.
+ olFolderNotes = 12, // The Notes folder.
+ olFolderOutbox = 4, // The Outbox folder.
+ olFolderSentMail = 5, // The Sent Mail folder.
+ olFolderServerFailures = 22, // The Server Failures folder (subfolder of Sync Issues folder). Only available for an Exchange account.
+ olFolderSyncIssues = 20, // The Sync Issues folder. Only available for an Exchange account.
+ olFolderTasks = 13, // The Tasks folder.
+ olFolderToDo = 28, // The To Do folder.
+ olPublicFoldersAllPublicFolders = 18, // The All Public Folders folder in the Exchange Public Folders store. Only available for an Exchange account.
+ olFolderRssFeeds = 25 // The RSS Feeds folder.
+ }
+
+ public enum OlItemType {
+ // Fields
+ olAppointmentItem = 1,
+ olContactItem = 2,
+ olDistributionListItem = 7,
+ olJournalItem = 4,
+ olMailItem = 0,
+ olNoteItem = 5,
+ olPostItem = 6,
+ olTaskItem = 3
+ }
+
+ public enum OlEditorType {
+ // Fields
+ olEditorHTML = 2,
+ olEditorRTF = 3,
+ olEditorText = 1,
+ olEditorWord = 4
+ }
+
+ public enum OlWindowState {
+ // Fields
+ olMaximized = 0,
+ olMinimized = 1,
+ olNormalWindow = 2
+ }
+
+ public enum OlInspectorClose {
+ // Fields
+ olDiscard = 1,
+ olPromptForSave = 2,
+ olSave = 0
+ }
+
+ public enum MsoTriState {
+ msoTrue = -1,
+ msoFalse = 0,
+ msoCTrue = 1,
+ msoTriStateToggle = -3,
+ msoTriStateMixed = -2
+ }
+
+ public enum OlReoccurenceState {
+ olApptException,
+ olApptMaster,
+ olApptNotRecurring,
+ olApptOccurrence
+ }
+
+ public enum MsoScaleFrom {
+ msoScaleFromTopLeft = 0,
+ msoScaleFromMiddle = 1,
+ msoScaleFromBottomRight = 2
+ }
+}
diff --git a/GreenshotOfficePlugin/OfficeInterop/OutlookUtils.cs b/GreenshotOfficePlugin/OfficeInterop/OutlookUtils.cs
new file mode 100644
index 000000000..fa27c4c7d
--- /dev/null
+++ b/GreenshotOfficePlugin/OfficeInterop/OutlookUtils.cs
@@ -0,0 +1,853 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+using System;
+using System.Runtime.InteropServices;
+
+namespace Greenshot.Interop.Office {
+ enum PT : uint {
+ PT_UNSPECIFIED = 0, /* (Reserved for interface use) type doesn't matter to caller */
+ PT_NULL = 1, /* NULL property value */
+ PT_I2 = 2, /* Signed 16-bit value */
+ PT_LONG = 3, /* Signed 32-bit value */
+ PT_R4 = 4, /* 4-byte floating point */
+ PT_DOUBLE = 5, /* Floating point double */
+ PT_CURRENCY = 6, /* Signed 64-bit int (decimal w/ 4 digits right of decimal pt) */
+ PT_APPTIME = 7, /* Application time */
+ PT_ERROR = 10, /* 32-bit error value */
+ PT_BOOLEAN = 11, /* 16-bit boolean (non-zero true, */
+ // Use PT_BOOLEAN_DESKTOP to be specific instead of using PT_BOOLEAN which is mapped to 2 in addrmapi.h
+ PT_BOOLEAN_DESKTOP = 11, /* 16-bit boolean (non-zero true) */
+ PT_OBJECT = 13, /* Embedded object in a property */
+ PT_I8 = 20, /* 8-byte signed integer */
+ PT_STRING8 = 30, /* Null terminated 8-bit character string */
+ PT_UNICODE = 31, /* Null terminated Unicode string */
+ PT_SYSTIME = 64, /* FILETIME 64-bit int w/ number of 100ns periods since Jan 1,1601 */
+ PT_CLSID = 72, /* OLE GUID */
+ PT_BINARY = 258, /* Uninterpreted (counted byte array) */
+
+ PT_TSTRING = PT_UNICODE
+ };
+
+ public enum PropTags : uint {
+ PR_ERROR = 10,
+
+ // Common non-transmittable
+ PR_ENTRYID = PT.PT_BINARY | 0x0FFF << 16,
+ PR_OBJECT_TYPE = PT.PT_LONG | 0x0FFE << 16,
+ PR_ICON = PT.PT_BINARY | 0x0FFD << 16,
+ PR_MINI_ICON = PT.PT_BINARY | 0x0FFC << 16,
+ PR_STORE_ENTRYID = PT.PT_BINARY | 0x0FFB << 16,
+ PR_STORE_RECORD_KEY = PT.PT_BINARY | 0x0FFA << 16,
+ PR_RECORD_KEY = PT.PT_BINARY | 0x0FF9 << 16,
+ PR_MAPPING_SIGNATURE = PT.PT_BINARY | 0x0FF8 << 16,
+ PR_ACCESS_LEVEL = PT.PT_LONG | 0x0FF7 << 16,
+ PR_INSTANCE_KEY = PT.PT_BINARY | 0x0FF6 << 16,
+ PR_ROW_TYPE = PT.PT_LONG | 0x0FF5 << 16,
+ PR_ACCESS = PT.PT_LONG | 0x0FF4 << 16,
+
+ // Common transmittable
+ PR_ROWID = PT.PT_LONG | 0x3000 << 16,
+ PR_DISPLAY_NAME = PT.PT_TSTRING | 0x3001 << 16,
+ PR_DISPLAY_NAME_W = PT.PT_UNICODE | 0x3001 << 16,
+ PR_DISPLAY_NAME_A = PT.PT_STRING8 | 0x3001 << 16,
+ PR_ADDRTYPE = PT.PT_TSTRING | 0x3002 << 16,
+ PR_ADDRTYPE_W = PT.PT_UNICODE | 0x3002 << 16,
+ PR_ADDRTYPE_A = PT.PT_STRING8 | 0x3002 << 16,
+ PR_EMAIL_ADDRESS = PT.PT_TSTRING | 0x3003 << 16,
+ PR_EMAIL_ADDRESS_W = PT.PT_UNICODE | 0x3003 << 16,
+ PR_EMAIL_ADDRESS_A = PT.PT_STRING8 | 0x3003 << 16,
+ PR_COMMENT = PT.PT_TSTRING | 0x3004 << 16,
+ PR_COMMENT_W = PT.PT_UNICODE | 0x3004 << 16,
+ PR_COMMENT_A = PT.PT_STRING8 | 0x3004 << 16,
+ PR_DEPTH = PT.PT_LONG | 0x3005 << 16,
+ PR_PROVIDER_DISPLAY = PT.PT_TSTRING | 0x3006 << 16,
+ PR_PROVIDER_DISPLAY_W = PT.PT_UNICODE | 0x3006 << 16,
+ PR_PROVIDER_DISPLAY_A = PT.PT_STRING8 | 0x3006 << 16,
+ PR_CREATION_TIME = PT.PT_SYSTIME | 0x3007 << 16,
+ PR_LAST_MODIFICATION_TIME = PT.PT_SYSTIME | 0x3008 << 16,
+ PR_RESOURCE_FLAGS = PT.PT_LONG | 0x3009 << 16,
+ PR_PROVIDER_DLL_NAME = PT.PT_TSTRING | 0x300A << 16,
+ PR_PROVIDER_DLL_NAME_W = PT.PT_UNICODE | 0x300A << 16,
+ PR_PROVIDER_DLL_NAME_A = PT.PT_STRING8 | 0x300A << 16,
+ PR_SEARCH_KEY = PT.PT_BINARY | 0x300B << 16,
+ PR_PROVIDER_UID = PT.PT_BINARY | 0x300C << 16,
+ PR_PROVIDER_ORDINAL = PT.PT_LONG | 0x300D << 16,
+
+ // Message store specific
+ PR_DEFAULT_STORE = PT.PT_BOOLEAN | 0x3400 << 16,
+ PR_STORE_SUPPORT_MASK = PT.PT_LONG | 0x340D << 16,
+ PR_STORE_STATE = PT.PT_LONG | 0x340E << 16,
+
+ PR_IPM_SUBTREE_SEARCH_KEY = PT.PT_BINARY | 0x3410 << 16,
+ PR_IPM_OUTBOX_SEARCH_KEY = PT.PT_BINARY | 0x3411 << 16,
+ PR_IPM_WASTEBASKET_SEARCH_KEY = PT.PT_BINARY | 0x3412 << 16,
+ PR_IPM_SENTMAIL_SEARCH_KEY = PT.PT_BINARY | 0x3413 << 16,
+ PR_MDB_PROVIDER = PT.PT_BINARY | 0x3414 << 16,
+ PR_RECEIVE_FOLDER_SETTINGS = PT.PT_OBJECT | 0x3415 << 16,
+
+ PR_VALID_FOLDER_MASK = PT.PT_LONG | 0x35DF << 16,
+ PR_IPM_SUBTREE_ENTRYID = PT.PT_BINARY | 0x35E0 << 16,
+
+ PR_IPM_OUTBOX_ENTRYID = PT.PT_BINARY | 0x35E2 << 16,
+ PR_IPM_WASTEBASKET_ENTRYID = PT.PT_BINARY | 0x35E3 << 16,
+ PR_IPM_SENTMAIL_ENTRYID = PT.PT_BINARY | 0x35E4 << 16,
+ PR_VIEWS_ENTRYID = PT.PT_BINARY | 0x35E5 << 16,
+ PR_COMMON_VIEWS_ENTRYID = PT.PT_BINARY | 0x35E6 << 16,
+ PR_FINDER_ENTRYID = PT.PT_BINARY | 0x35E7 << 16,
+ PR_ATTACH_CONTENT_ID = PT.PT_TSTRING | (0x3712 << 16),
+ PR_ATTACH_CONTENT_ID_A = PT.PT_STRING8 | (0x3712 << 16),
+ PR_ATTACH_CONTENT_ID_W = PT.PT_TSTRING | (0x3712 << 16),
+ PR_ATTACH_CONTENT_LOCATION = PT.PT_TSTRING | (0x3713 << 16),
+ PR_ATTACH_CONTENT_LOCATION_A = PT.PT_STRING8 | (0x3713 << 16),
+ PR_ATTACH_CONTENT_LOCATION_W = PT.PT_TSTRING | (0x3713 << 16),
+
+ // Message non-transmittable properties
+ PR_CURRENT_VERSION = PT.PT_I8 | 0x0E00 << 16,
+ PR_DELETE_AFTER_SUBMIT = PT.PT_BOOLEAN | 0x0E01 << 16,
+ PR_DISPLAY_BCC = PT.PT_TSTRING | 0x0E02 << 16,
+ PR_DISPLAY_BCC_W = PT.PT_UNICODE | 0x0E02 << 16,
+ PR_DISPLAY_BCC_A = PT.PT_STRING8 | 0x0E02 << 16,
+ PR_DISPLAY_CC = PT.PT_TSTRING | 0x0E03 << 16,
+ PR_DISPLAY_CC_W = PT.PT_UNICODE | 0x0E03 << 16,
+ PR_DISPLAY_CC_A = PT.PT_STRING8 | 0x0E03 << 16,
+ PR_DISPLAY_TO = PT.PT_TSTRING | 0x0E04 << 16,
+ PR_DISPLAY_TO_W = PT.PT_UNICODE | 0x0E04 << 16,
+ PR_DISPLAY_TO_A = PT.PT_STRING8 | 0x0E04 << 16,
+ PR_PARENT_DISPLAY = PT.PT_TSTRING | 0x0E05 << 16,
+ PR_PARENT_DISPLAY_W = PT.PT_UNICODE | 0x0E05 << 16,
+ PR_PARENT_DISPLAY_A = PT.PT_STRING8 | 0x0E05 << 16,
+ PR_MESSAGE_DELIVERY_TIME = PT.PT_SYSTIME | 0x0E06 << 16,
+ PR_MESSAGE_FLAGS = PT.PT_LONG | 0x0E07 << 16,
+ PR_MESSAGE_SIZE = PT.PT_LONG | 0x0E08 << 16,
+ PR_PARENT_ENTRYID = PT.PT_BINARY | 0x0E09 << 16,
+ PR_SENTMAIL_ENTRYID = PT.PT_BINARY | 0x0E0A << 16,
+ PR_CORRELATE = PT.PT_BOOLEAN | 0x0E0C << 16,
+ PR_CORRELATE_MTSID = PT.PT_BINARY | 0x0E0D << 16,
+ PR_DISCRETE_VALUES = PT.PT_BOOLEAN | 0x0E0E << 16,
+ PR_RESPONSIBILITY = PT.PT_BOOLEAN | 0x0E0F << 16,
+ PR_SPOOLER_STATUS = PT.PT_LONG | 0x0E10 << 16,
+ PR_TRANSPORT_STATUS = PT.PT_LONG | 0x0E11 << 16,
+ PR_MESSAGE_RECIPIENTS = PT.PT_OBJECT | 0x0E12 << 16,
+ PR_MESSAGE_ATTACHMENTS = PT.PT_OBJECT | 0x0E13 << 16,
+ PR_SUBMIT_FLAGS = PT.PT_LONG | 0x0E14 << 16,
+ PR_RECIPIENT_STATUS = PT.PT_LONG | 0x0E15 << 16,
+ PR_TRANSPORT_KEY = PT.PT_LONG | 0x0E16 << 16,
+ PR_MSG_STATUS = PT.PT_LONG | 0x0E17 << 16,
+ PR_MESSAGE_DOWNLOAD_TIME = PT.PT_LONG | 0x0E18 << 16,
+ PR_CREATION_VERSION = PT.PT_I8 | 0x0E19 << 16,
+ PR_MODIFY_VERSION = PT.PT_I8 | 0x0E1A << 16,
+ PR_HASATTACH = PT.PT_BOOLEAN | 0x0E1B << 16,
+ PR_BODY_CRC = PT.PT_LONG | 0x0E1C << 16,
+ PR_NORMALIZED_SUBJECT = PT.PT_TSTRING | 0x0E1D << 16,
+ PR_NORMALIZED_SUBJECT_W = PT.PT_UNICODE | 0x0E1D << 16,
+ PR_NORMALIZED_SUBJECT_A = PT.PT_STRING8 | 0x0E1D << 16,
+ PR_RTF_IN_SYNC = PT.PT_BOOLEAN | 0x0E1F << 16,
+ PR_ATTACH_SIZE = PT.PT_LONG | 0x0E20 << 16,
+ PR_ATTACH_NUM = PT.PT_LONG | 0x0E21 << 16,
+ PR_PREPROCESS = PT.PT_BOOLEAN | 0x0E22 << 16,
+
+ // Message recipient properties
+ PR_CONTENT_INTEGRITY_CHECK = PT.PT_BINARY | 0x0C00 << 16,
+ PR_EXPLICIT_CONVERSION = PT.PT_LONG | 0x0C01 << 16,
+ PR_IPM_RETURN_REQUESTED = PT.PT_BOOLEAN | 0x0C02 << 16,
+ PR_MESSAGE_TOKEN = PT.PT_BINARY | 0x0C03 << 16,
+ PR_NDR_REASON_CODE = PT.PT_LONG | 0x0C04 << 16,
+ PR_NDR_DIAG_CODE = PT.PT_LONG | 0x0C05 << 16,
+ PR_NON_RECEIPT_NOTIFICATION_REQUESTED = PT.PT_BOOLEAN | 0x0C06 << 16,
+ PR_DELIVERY_POINT = PT.PT_LONG | 0x0C07 << 16,
+
+ PR_ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED = PT.PT_BOOLEAN | 0x0C08 << 16,
+ PR_ORIGINATOR_REQUESTED_ALTERNATE_RECIPIENT = PT.PT_BINARY | 0x0C09 << 16,
+ PR_PHYSICAL_DELIVERY_BUREAU_FAX_DELIVERY = PT.PT_BOOLEAN | 0x0C0A << 16,
+ PR_PHYSICAL_DELIVERY_MODE = PT.PT_LONG | 0x0C0B << 16,
+ PR_PHYSICAL_DELIVERY_REPORT_REQUEST = PT.PT_LONG | 0x0C0C << 16,
+ PR_PHYSICAL_FORWARDING_ADDRESS = PT.PT_BINARY | 0x0C0D << 16,
+ PR_PHYSICAL_FORWARDING_ADDRESS_REQUESTED = PT.PT_BOOLEAN | 0x0C0E << 16,
+ PR_PHYSICAL_FORWARDING_PROHIBITED = PT.PT_BOOLEAN | 0x0C0F << 16,
+ PR_PHYSICAL_RENDITION_ATTRIBUTES = PT.PT_BINARY | 0x0C10 << 16,
+ PR_PROOF_OF_DELIVERY = PT.PT_BINARY | 0x0C11 << 16,
+ PR_PROOF_OF_DELIVERY_REQUESTED = PT.PT_BOOLEAN | 0x0C12 << 16,
+ PR_RECIPIENT_CERTIFICATE = PT.PT_BINARY | 0x0C13 << 16,
+ PR_RECIPIENT_NUMBER_FOR_ADVICE = PT.PT_TSTRING | 0x0C14 << 16,
+ PR_RECIPIENT_NUMBER_FOR_ADVICE_W = PT.PT_UNICODE | 0x0C14 << 16,
+ PR_RECIPIENT_NUMBER_FOR_ADVICE_A = PT.PT_STRING8 | 0x0C14 << 16,
+ PR_RECIPIENT_TYPE = PT.PT_LONG | 0x0C15 << 16,
+ PR_REGISTERED_MAIL_TYPE = PT.PT_LONG | 0x0C16 << 16,
+ PR_REPLY_REQUESTED = PT.PT_BOOLEAN | 0x0C17 << 16,
+ //PR_REQUESTED_DELIVERY_METHOD = PT.PT_LONG | 0x0C18 << 16,
+ PR_SENDER_ENTRYID = PT.PT_BINARY | 0x0C19 << 16,
+ PR_SENDER_NAME = PT.PT_TSTRING | 0x0C1A << 16,
+ PR_SENDER_NAME_W = PT.PT_UNICODE | 0x0C1A << 16,
+ PR_SENDER_NAME_A = PT.PT_STRING8 | 0x0C1A << 16,
+ PR_SUPPLEMENTARY_INFO = PT.PT_TSTRING | 0x0C1B << 16,
+ PR_SUPPLEMENTARY_INFO_W = PT.PT_UNICODE | 0x0C1B << 16,
+ PR_SUPPLEMENTARY_INFO_A = PT.PT_STRING8 | 0x0C1B << 16,
+ PR_TYPE_OF_MTS_USER = PT.PT_LONG | 0x0C1C << 16,
+ PR_SENDER_SEARCH_KEY = PT.PT_BINARY | 0x0C1D << 16,
+ PR_SENDER_ADDRTYPE = PT.PT_TSTRING | 0x0C1E << 16,
+ PR_SENDER_ADDRTYPE_W = PT.PT_UNICODE | 0x0C1E << 16,
+ PR_SENDER_ADDRTYPE_A = PT.PT_STRING8 | 0x0C1E << 16,
+ PR_SENDER_EMAIL_ADDRESS = PT.PT_TSTRING | 0x0C1F << 16,
+ PR_SENDER_EMAIL_ADDRESS_W = PT.PT_UNICODE | 0x0C1F << 16,
+ PR_SENDER_EMAIL_ADDRESS_A = PT.PT_STRING8 | 0x0C1F << 16,
+
+ // Message envelope properties
+ PR_ACKNOWLEDGEMENT_MODE = PT.PT_LONG | 0x0001 << 16,
+ PR_ALTERNATE_RECIPIENT_ALLOWED = PT.PT_BOOLEAN | 0x0002 << 16,
+ PR_AUTHORIZING_USERS = PT.PT_BINARY | 0x0003 << 16,
+ PR_AUTO_FORWARD_COMMENT = PT.PT_TSTRING | 0x0004 << 16,
+ PR_AUTO_FORWARD_COMMENT_W = PT.PT_UNICODE | 0x0004 << 16,
+ PR_AUTO_FORWARD_COMMENT_A = PT.PT_STRING8 | 0x0004 << 16,
+ PR_AUTO_FORWARDED = PT.PT_BOOLEAN | 0x0005 << 16,
+ PR_CONTENT_CONFIDENTIALITY_ALGORITHM_ID = PT.PT_BINARY | 0x0006 << 16,
+ PR_CONTENT_CORRELATOR = PT.PT_BINARY | 0x0007 << 16,
+ PR_CONTENT_IDENTIFIER = PT.PT_TSTRING | 0x0008 << 16,
+ PR_CONTENT_IDENTIFIER_W = PT.PT_UNICODE | 0x0008 << 16,
+ PR_CONTENT_IDENTIFIER_A = PT.PT_STRING8 | 0x0008 << 16,
+ PR_CONTENT_LENGTH = PT.PT_LONG | 0x0009 << 16,
+ PR_CONTENT_RETURN_REQUESTED = PT.PT_BOOLEAN | 0x000A << 16,
+
+ // Message envelope properties
+ PR_CONVERSATION_KEY = PT.PT_BINARY | 0x000B << 16,
+
+ PR_CONVERSION_EITS = PT.PT_BINARY | 0x000C << 16,
+ PR_CONVERSION_WITH_LOSS_PROHIBITED = PT.PT_BOOLEAN | 0x000D << 16,
+ PR_CONVERTED_EITS = PT.PT_BINARY | 0x000E << 16,
+ PR_DEFERRED_DELIVERY_TIME = PT.PT_SYSTIME | 0x000F << 16,
+ PR_DELIVER_TIME = PT.PT_SYSTIME | 0x0010 << 16,
+ PR_DISCARD_REASON = PT.PT_LONG | 0x0011 << 16,
+ PR_DISCLOSURE_OF_RECIPIENTS = PT.PT_BOOLEAN | 0x0012 << 16,
+ PR_DL_EXPANSION_HISTORY = PT.PT_BINARY | 0x0013 << 16,
+ PR_DL_EXPANSION_PROHIBITED = PT.PT_BOOLEAN | 0x0014 << 16,
+ PR_EXPIRY_TIME = PT.PT_SYSTIME | 0x0015 << 16,
+ PR_IMPLICIT_CONVERSION_PROHIBITED = PT.PT_BOOLEAN | 0x0016 << 16,
+ PR_IMPORTANCE = PT.PT_LONG | 0x0017 << 16,
+ PR_IPM_ID = PT.PT_BINARY | 0x0018 << 16,
+ PR_LATEST_DELIVERY_TIME = PT.PT_SYSTIME | 0x0019 << 16,
+ PR_MESSAGE_CLASS = PT.PT_TSTRING | 0x001A << 16,
+ PR_MESSAGE_CLASS_W = PT.PT_UNICODE | 0x001A << 16,
+ PR_MESSAGE_CLASS_A = PT.PT_STRING8 | 0x001A << 16,
+ PR_MESSAGE_DELIVERY_ID = PT.PT_BINARY | 0x001B << 16,
+
+ PR_MESSAGE_SECURITY_LABEL = PT.PT_BINARY | 0x001E << 16,
+ PR_OBSOLETED_IPMS = PT.PT_BINARY | 0x001F << 16,
+ PR_ORIGINALLY_INTENDED_RECIPIENT_NAME = PT.PT_BINARY | 0x0020 << 16,
+ PR_ORIGINAL_EITS = PT.PT_BINARY | 0x0021 << 16,
+ PR_ORIGINATOR_CERTIFICATE = PT.PT_BINARY | 0x0022 << 16,
+ PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED = PT.PT_BOOLEAN | 0x0023 << 16,
+ PR_ORIGINATOR_RETURN_ADDRESS = PT.PT_BINARY | 0x0024 << 16,
+
+ PR_PARENT_KEY = PT.PT_BINARY | 0x0025 << 16,
+ PR_PRIORITY = PT.PT_LONG | 0x0026 << 16,
+
+ PR_ORIGIN_CHECK = PT.PT_BINARY | 0x0027 << 16,
+ PR_PROOF_OF_SUBMISSION_REQUESTED = PT.PT_BOOLEAN | 0x0028 << 16,
+ PR_READ_RECEIPT_REQUESTED = PT.PT_BOOLEAN | 0x0029 << 16,
+ PR_RECEIPT_TIME = PT.PT_SYSTIME | 0x002A << 16,
+ PR_RECIPIENT_REASSIGNMENT_PROHIBITED = PT.PT_BOOLEAN | 0x002B << 16,
+ PR_REDIRECTION_HISTORY = PT.PT_BINARY | 0x002C << 16,
+ PR_RELATED_IPMS = PT.PT_BINARY | 0x002D << 16,
+ PR_ORIGINAL_SENSITIVITY = PT.PT_LONG | 0x002E << 16,
+ PR_LANGUAGES = PT.PT_TSTRING | 0x002F << 16,
+ PR_LANGUAGES_W = PT.PT_UNICODE | 0x002F << 16,
+ PR_LANGUAGES_A = PT.PT_STRING8 | 0x002F << 16,
+ PR_REPLY_TIME = PT.PT_SYSTIME | 0x0030 << 16,
+ PR_REPORT_TAG = PT.PT_BINARY | 0x0031 << 16,
+ PR_REPORT_TIME = PT.PT_SYSTIME | 0x0032 << 16,
+ PR_RETURNED_IPM = PT.PT_BOOLEAN | 0x0033 << 16,
+ PR_SECURITY = PT.PT_LONG | 0x0034 << 16,
+ PR_INCOMPLETE_COPY = PT.PT_BOOLEAN | 0x0035 << 16,
+ PR_SENSITIVITY = PT.PT_LONG | 0x0036 << 16,
+ PR_SUBJECT = PT.PT_TSTRING | 0x0037 << 16,
+ PR_SUBJECT_W = PT.PT_UNICODE | 0x0037 << 16,
+ PR_SUBJECT_A = PT.PT_STRING8 | 0x0037 << 16,
+ PR_SUBJECT_IPM = PT.PT_BINARY | 0x0038 << 16,
+ PR_CLIENT_SUBMIT_TIME = PT.PT_SYSTIME | 0x0039 << 16,
+ PR_REPORT_NAME = PT.PT_TSTRING | 0x003A << 16,
+ PR_REPORT_NAME_W = PT.PT_UNICODE | 0x003A << 16,
+ PR_REPORT_NAME_A = PT.PT_STRING8 | 0x003A << 16,
+ PR_SENT_REPRESENTING_SEARCH_KEY = PT.PT_BINARY | 0x003B << 16,
+ PR_X400_CONTENT_TYPE = PT.PT_BINARY | 0x003C << 16,
+ PR_SUBJECT_PREFIX = PT.PT_TSTRING | 0x003D << 16,
+ PR_SUBJECT_PREFIX_W = PT.PT_UNICODE | 0x003D << 16,
+ PR_SUBJECT_PREFIX_A = PT.PT_STRING8 | 0x003D << 16,
+ PR_NON_RECEIPT_REASON = PT.PT_LONG | 0x003E << 16,
+ PR_RECEIVED_BY_ENTRYID = PT.PT_BINARY | 0x003F << 16,
+ PR_RECEIVED_BY_NAME = PT.PT_TSTRING | 0x0040 << 16,
+ PR_RECEIVED_BY_NAME_W = PT.PT_UNICODE | 0x0040 << 16,
+ PR_RECEIVED_BY_NAME_A = PT.PT_STRING8 | 0x0040 << 16,
+ PR_SENT_REPRESENTING_ENTRYID = PT.PT_BINARY | 0x0041 << 16,
+ PR_SENT_REPRESENTING_NAME = PT.PT_TSTRING | 0x0042 << 16,
+ PR_SENT_REPRESENTING_NAME_W = PT.PT_UNICODE | 0x0042 << 16,
+ PR_SENT_REPRESENTING_NAME_A = PT.PT_STRING8 | 0x0042 << 16,
+ PR_RCVD_REPRESENTING_ENTRYID = PT.PT_BINARY | 0x0043 << 16,
+ PR_RCVD_REPRESENTING_NAME = PT.PT_TSTRING | 0x0044 << 16,
+ PR_RCVD_REPRESENTING_NAME_W = PT.PT_UNICODE | 0x0044 << 16,
+ PR_RCVD_REPRESENTING_NAME_A = PT.PT_STRING8 | 0x0044 << 16,
+ PR_REPORT_ENTRYID = PT.PT_BINARY | 0x0045 << 16,
+ PR_READ_RECEIPT_ENTRYID = PT.PT_BINARY | 0x0046 << 16,
+ PR_MESSAGE_SUBMISSION_ID = PT.PT_BINARY | 0x0047 << 16,
+ PR_PROVIDER_SUBMIT_TIME = PT.PT_SYSTIME | 0x0048 << 16,
+ PR_ORIGINAL_SUBJECT = PT.PT_TSTRING | 0x0049 << 16,
+ PR_ORIGINAL_SUBJECT_W = PT.PT_UNICODE | 0x0049 << 16,
+ PR_ORIGINAL_SUBJECT_A = PT.PT_STRING8 | 0x0049 << 16,
+ PR_DISC_VAL = PT.PT_BOOLEAN | 0x004A << 16,
+ PR_ORIG_MESSAGE_CLASS = PT.PT_TSTRING | 0x004B << 16,
+ PR_ORIG_MESSAGE_CLASS_W = PT.PT_UNICODE | 0x004B << 16,
+ PR_ORIG_MESSAGE_CLASS_A = PT.PT_STRING8 | 0x004B << 16,
+ PR_ORIGINAL_AUTHOR_ENTRYID = PT.PT_BINARY | 0x004C << 16,
+ PR_ORIGINAL_AUTHOR_NAME = PT.PT_TSTRING | 0x004D << 16,
+ PR_ORIGINAL_AUTHOR_NAME_W = PT.PT_UNICODE | 0x004D << 16,
+ PR_ORIGINAL_AUTHOR_NAME_A = PT.PT_STRING8 | 0x004D << 16,
+ PR_ORIGINAL_SUBMIT_TIME = PT.PT_SYSTIME | 0x004E << 16,
+ PR_REPLY_RECIPIENT_ENTRIES = PT.PT_BINARY | 0x004F << 16,
+ PR_REPLY_RECIPIENT_NAMES = PT.PT_TSTRING | 0x0050 << 16,
+ PR_REPLY_RECIPIENT_NAMES_W = PT.PT_UNICODE | 0x0050 << 16,
+ PR_REPLY_RECIPIENT_NAMES_A = PT.PT_STRING8 | 0x0050 << 16,
+
+ PR_RECEIVED_BY_SEARCH_KEY = PT.PT_BINARY | 0x0051 << 16,
+ PR_RCVD_REPRESENTING_SEARCH_KEY = PT.PT_BINARY | 0x0052 << 16,
+ PR_READ_RECEIPT_SEARCH_KEY = PT.PT_BINARY | 0x0053 << 16,
+ PR_REPORT_SEARCH_KEY = PT.PT_BINARY | 0x0054 << 16,
+ PR_ORIGINAL_DELIVERY_TIME = PT.PT_SYSTIME | 0x0055 << 16,
+ PR_ORIGINAL_AUTHOR_SEARCH_KEY = PT.PT_BINARY | 0x0056 << 16,
+
+ PR_MESSAGE_TO_ME = PT.PT_BOOLEAN | 0x0057 << 16,
+ PR_MESSAGE_CC_ME = PT.PT_BOOLEAN | 0x0058 << 16,
+ PR_MESSAGE_RECIP_ME = PT.PT_BOOLEAN | 0x0059 << 16,
+
+ PR_ORIGINAL_SENDER_NAME = PT.PT_TSTRING | 0x005A << 16,
+ PR_ORIGINAL_SENDER_NAME_W = PT.PT_UNICODE | 0x005A << 16,
+ PR_ORIGINAL_SENDER_NAME_A = PT.PT_STRING8 | 0x005A << 16,
+ PR_ORIGINAL_SENDER_ENTRYID = PT.PT_BINARY | 0x005B << 16,
+ PR_ORIGINAL_SENDER_SEARCH_KEY = PT.PT_BINARY | 0x005C << 16,
+ PR_ORIGINAL_SENT_REPRESENTING_NAME = PT.PT_TSTRING | 0x005D << 16,
+ PR_ORIGINAL_SENT_REPRESENTING_NAME_W = PT.PT_UNICODE | 0x005D << 16,
+ PR_ORIGINAL_SENT_REPRESENTING_NAME_A = PT.PT_STRING8 | 0x005D << 16,
+ PR_ORIGINAL_SENT_REPRESENTING_ENTRYID = PT.PT_BINARY | 0x005E << 16,
+ PR_ORIGINAL_SENT_REPRESENTING_SEARCH_KEY = PT.PT_BINARY | 0x005F << 16,
+
+ PR_START_DATE = PT.PT_SYSTIME | 0x0060 << 16,
+ PR_END_DATE = PT.PT_SYSTIME | 0x0061 << 16,
+ PR_OWNER_APPT_ID = PT.PT_LONG | 0x0062 << 16,
+ //PR_RESPONSE_REQUESTED = PT.PT_BOOLEAN | 0x0063 << 16,
+
+ PR_SENT_REPRESENTING_ADDRTYPE = PT.PT_TSTRING | 0x0064 << 16,
+ PR_SENT_REPRESENTING_ADDRTYPE_W = PT.PT_UNICODE | 0x0064 << 16,
+ PR_SENT_REPRESENTING_ADDRTYPE_A = PT.PT_STRING8 | 0x0064 << 16,
+ PR_SENT_REPRESENTING_EMAIL_ADDRESS = PT.PT_TSTRING | 0x0065 << 16,
+ PR_SENT_REPRESENTING_EMAIL_ADDRESS_W = PT.PT_UNICODE | 0x0065 << 16,
+ PR_SENT_REPRESENTING_EMAIL_ADDRESS_A = PT.PT_STRING8 | 0x0065 << 16,
+
+ PR_ORIGINAL_SENDER_ADDRTYPE = PT.PT_TSTRING | 0x0066 << 16,
+ PR_ORIGINAL_SENDER_ADDRTYPE_W = PT.PT_UNICODE | 0x0066 << 16,
+ PR_ORIGINAL_SENDER_ADDRTYPE_A = PT.PT_STRING8 | 0x0066 << 16,
+ PR_ORIGINAL_SENDER_EMAIL_ADDRESS = PT.PT_TSTRING | 0x0067 << 16,
+ PR_ORIGINAL_SENDER_EMAIL_ADDRESS_W = PT.PT_UNICODE | 0x0067 << 16,
+ PR_ORIGINAL_SENDER_EMAIL_ADDRESS_A = PT.PT_STRING8 | 0x0067 << 16,
+
+ PR_ORIGINAL_SENT_REPRESENTING_ADDRTYPE = PT.PT_TSTRING | 0x0068 << 16,
+ PR_ORIGINAL_SENT_REPRESENTING_ADDRTYPE_W = PT.PT_UNICODE | 0x0068 << 16,
+ PR_ORIGINAL_SENT_REPRESENTING_ADDRTYPE_A = PT.PT_STRING8 | 0x0068 << 16,
+ PR_ORIGINAL_SENT_REPRESENTING_EMAIL_ADDRESS = PT.PT_TSTRING | 0x0069 << 16,
+ PR_ORIGINAL_SENT_REPRESENTING_EMAIL_ADDRESS_W = PT.PT_UNICODE | 0x0069 << 16,
+ PR_ORIGINAL_SENT_REPRESENTING_EMAIL_ADDRESS_A = PT.PT_STRING8 | 0x0069 << 16,
+
+ PR_CONVERSATION_TOPIC = PT.PT_TSTRING | 0x0070 << 16,
+ PR_CONVERSATION_TOPIC_W = PT.PT_UNICODE | 0x0070 << 16,
+ PR_CONVERSATION_TOPIC_A = PT.PT_STRING8 | 0x0070 << 16,
+ PR_CONVERSATION_INDEX = PT.PT_BINARY | 0x0071 << 16,
+
+ PR_ORIGINAL_DISPLAY_BCC = PT.PT_TSTRING | 0x0072 << 16,
+ PR_ORIGINAL_DISPLAY_BCC_W = PT.PT_UNICODE | 0x0072 << 16,
+ PR_ORIGINAL_DISPLAY_BCC_A = PT.PT_STRING8 | 0x0072 << 16,
+ PR_ORIGINAL_DISPLAY_CC = PT.PT_TSTRING | 0x0073 << 16,
+ PR_ORIGINAL_DISPLAY_CC_W = PT.PT_UNICODE | 0x0073 << 16,
+ PR_ORIGINAL_DISPLAY_CC_A = PT.PT_STRING8 | 0x0073 << 16,
+ PR_ORIGINAL_DISPLAY_TO = PT.PT_TSTRING | 0x0074 << 16,
+ PR_ORIGINAL_DISPLAY_TO_W = PT.PT_UNICODE | 0x0074 << 16,
+ PR_ORIGINAL_DISPLAY_TO_A = PT.PT_STRING8 | 0x0074 << 16,
+
+ PR_RECEIVED_BY_ADDRTYPE = PT.PT_TSTRING | 0x0075 << 16,
+ PR_RECEIVED_BY_ADDRTYPE_W = PT.PT_UNICODE | 0x0075 << 16,
+ PR_RECEIVED_BY_ADDRTYPE_A = PT.PT_STRING8 | 0x0075 << 16,
+ PR_RECEIVED_BY_EMAIL_ADDRESS = PT.PT_TSTRING | 0x0076 << 16,
+ PR_RECEIVED_BY_EMAIL_ADDRESS_W = PT.PT_UNICODE | 0x0076 << 16,
+ PR_RECEIVED_BY_EMAIL_ADDRESS_A = PT.PT_STRING8 | 0x0076 << 16,
+
+ PR_RCVD_REPRESENTING_ADDRTYPE = PT.PT_TSTRING | 0x0077 << 16,
+ PR_RCVD_REPRESENTING_ADDRTYPE_W = PT.PT_UNICODE | 0x0077 << 16,
+ PR_RCVD_REPRESENTING_ADDRTYPE_A = PT.PT_STRING8 | 0x0077 << 16,
+ PR_RCVD_REPRESENTING_EMAIL_ADDRESS = PT.PT_TSTRING | 0x0078 << 16,
+ PR_RCVD_REPRESENTING_EMAIL_ADDRESS_W = PT.PT_UNICODE | 0x0078 << 16,
+ PR_RCVD_REPRESENTING_EMAIL_ADDRESS_A = PT.PT_STRING8 | 0x0078 << 16,
+
+ PR_ORIGINAL_AUTHOR_ADDRTYPE = PT.PT_TSTRING | 0x0079 << 16,
+ PR_ORIGINAL_AUTHOR_ADDRTYPE_W = PT.PT_UNICODE | 0x0079 << 16,
+ PR_ORIGINAL_AUTHOR_ADDRTYPE_A = PT.PT_STRING8 | 0x0079 << 16,
+ PR_ORIGINAL_AUTHOR_EMAIL_ADDRESS = PT.PT_TSTRING | 0x007A << 16,
+ PR_ORIGINAL_AUTHOR_EMAIL_ADDRESS_W = PT.PT_UNICODE | 0x007A << 16,
+ PR_ORIGINAL_AUTHOR_EMAIL_ADDRESS_A = PT.PT_STRING8 | 0x007A << 16,
+
+ PR_ORIGINALLY_INTENDED_RECIP_ADDRTYPE = PT.PT_TSTRING | 0x007B << 16,
+ PR_ORIGINALLY_INTENDED_RECIP_ADDRTYPE_W = PT.PT_UNICODE | 0x007B << 16,
+ PR_ORIGINALLY_INTENDED_RECIP_ADDRTYPE_A = PT.PT_STRING8 | 0x007B << 16,
+ PR_ORIGINALLY_INTENDED_RECIP_EMAIL_ADDRESS = PT.PT_TSTRING | 0x007C << 16,
+ PR_ORIGINALLY_INTENDED_RECIP_EMAIL_ADDRESS_W = PT.PT_UNICODE | 0x007C << 16,
+ PR_ORIGINALLY_INTENDED_RECIP_EMAIL_ADDRESS_A = PT.PT_STRING8 | 0x007C << 16,
+
+ PR_TRANSPORT_MESSAGE_HEADERS = PT.PT_TSTRING | 0x007D << 16,
+ PR_TRANSPORT_MESSAGE_HEADERS_W = PT.PT_UNICODE | 0x007D << 16,
+ PR_TRANSPORT_MESSAGE_HEADERS_A = PT.PT_STRING8 | 0x007D << 16,
+
+ PR_DELEGATION = PT.PT_BINARY | 0x007E << 16,
+
+ PR_TNEF_CORRELATION_KEY = PT.PT_BINARY | 0x007F << 16,
+
+ // Message content properties
+ PR_BODY = PT.PT_TSTRING | 0x1000 << 16,
+ PR_BODY_W = PT.PT_UNICODE | 0x1000 << 16,
+ PR_BODY_A = PT.PT_STRING8 | 0x1000 << 16,
+ PR_REPORT_TEXT = PT.PT_TSTRING | 0x1001 << 16,
+ PR_REPORT_TEXT_W = PT.PT_UNICODE | 0x1001 << 16,
+ PR_REPORT_TEXT_A = PT.PT_STRING8 | 0x1001 << 16,
+ PR_ORIGINATOR_AND_DL_EXPANSION_HISTORY = PT.PT_BINARY | 0x1002 << 16,
+ PR_REPORTING_DL_NAME = PT.PT_BINARY | 0x1003 << 16,
+ PR_REPORTING_MTA_CERTIFICATE = PT.PT_BINARY | 0x1004 << 16,
+ };
+
+ public class OutlookUtils {
+ private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(OutlookUtils));
+ private const uint KEEP_OPEN_READONLY = 0x00000001;
+ private const uint KEEP_OPEN_READWRITE = 0x00000002;
+ private const uint FORCE_SAVE = 0x00000004;
+
+ #region MAPI Interface ID'S
+ // The Interface ID's are used to retrieve the specific MAPI Interfaces from the IUnknown Object
+ public const string IID_IMAPISession = "00020300-0000-0000-C000-000000000046";
+ public const string IID_IMAPIProp = "00020303-0000-0000-C000-000000000046";
+ public const string IID_IMAPITable = "00020301-0000-0000-C000-000000000046";
+ public const string IID_IMAPIMsgStore = "00020306-0000-0000-C000-000000000046";
+ public const string IID_IMAPIFolder = "0002030C-0000-0000-C000-000000000046";
+ public const string IID_IMAPISpoolerService = "0002031E-0000-0000-C000-000000000046";
+ public const string IID_IMAPIStatus = "0002031E-0000-0000-C000-000000000046";
+ public const string IID_IMessage = "00020307-0000-0000-C000-000000000046";
+ public const string IID_IAddrBook = "00020309-0000-0000-C000-000000000046";
+ public const string IID_IProfSect = "00020304-0000-0000-C000-000000000046";
+ public const string IID_IMAPIContainer = "0002030B-0000-0000-C000-000000000046";
+ public const string IID_IABContainer = "0002030D-0000-0000-C000-000000000046";
+ public const string IID_IMsgServiceAdmin = "0002031D-0000-0000-C000-000000000046";
+ public const string IID_IProfAdmin = "0002031C-0000-0000-C000-000000000046";
+ public const string IID_IMailUser = "0002030A-0000-0000-C000-000000000046";
+ public const string IID_IDistList = "0002030E-0000-0000-C000-000000000046";
+ public const string IID_IAttachment = "00020308-0000-0000-C000-000000000046";
+ public const string IID_IMAPIControl = "0002031B-0000-0000-C000-000000000046";
+ public const string IID_IMAPILogonRemote = "00020346-0000-0000-C000-000000000046";
+ public const string IID_IMAPIForm = "00020327-0000-0000-C000-000000000046";
+ #endregion
+
+ [ComVisible(false)]
+ [ComImport()]
+ [Guid(IID_IMAPIProp)]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ interface IMessage : IMAPIProp {
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int GetAttachmentTable();
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int OpenAttach();
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int CreateAttach();
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int DeleteAttach();
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int GetRecipientTable();
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int ModifyRecipients();
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int SubmitMessage();
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int SetReadFlag();
+ }
+ // [ComVisible(false)]
+ // [ComImport()]
+ // [Guid(IID_IMAPIFolder)]
+ // [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ // interface IMAPIFolder : IMAPIContainer {
+ // [return: MarshalAs(UnmanagedType.I4)]
+ // [PreserveSig]
+ // int CreateMessage(IntPtr interf, uint uFlags, [MarshalAs(UnmanagedType.Interface)] ref IMessage pMsg);
+ // [return: MarshalAs(UnmanagedType.I4)]
+ // [PreserveSig]
+ // int CopyMessages();
+ // [return: MarshalAs(UnmanagedType.I4)]
+ // [PreserveSig]
+ // int CreateFolder();
+ // [return: MarshalAs(UnmanagedType.I4)]
+ // [PreserveSig]
+ // int CopyFolder();
+ // [return: MarshalAs(UnmanagedType.I4)]
+ // [PreserveSig]
+ // int DeleteFolder();
+ // [return: MarshalAs(UnmanagedType.I4)]
+ // [PreserveSig]
+ // int SetReadFlags();
+ // [return: MarshalAs(UnmanagedType.I4)]
+ // [PreserveSig]
+ // int GetMessageStatus();
+ // [return: MarshalAs(UnmanagedType.I4)]
+ // [PreserveSig]
+ // int SetMessageStatus();
+ // [return: MarshalAs(UnmanagedType.I4)]
+ // [PreserveSig]
+ // int SaveContentsSort();
+ // [return: MarshalAs(UnmanagedType.I4)]
+ // [PreserveSig]
+ // int EmptyFolder();
+ // }
+ // [ComVisible(false)]
+ // [ComImport()]
+ // [Guid(IID_IMAPIContainer)]
+ // [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ // interface IMAPIContainer : IMAPIProp {
+ // [return: MarshalAs(UnmanagedType.I4)]
+ // [PreserveSig]
+ // int GetContentsTable(uint uFlags, [MarshalAs(UnmanagedType.Interface), Out] out outlook.Table tbl);
+ // [return: MarshalAs(UnmanagedType.I4)]
+ // [PreserveSig]
+ // int GetHierarchyTable();
+ // [return: MarshalAs(UnmanagedType.I4)]
+ // [PreserveSig]
+ // int OpenEntry();
+ // [return: MarshalAs(UnmanagedType.I4)]
+ // [PreserveSig]
+ // int SetSearchCriteria();
+ // [return: MarshalAs(UnmanagedType.I4)]
+ // [PreserveSig]
+ // int GetSearchCriteria();
+ // }
+
+ [ComVisible(false)]
+ [ComImport()]
+ [Guid(IID_IMAPIProp)]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ interface IMAPIProp {
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int GetLastError();
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int SaveChanges(
+ uint uFlags
+ );
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int GetProps();
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int GetPropList();
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int OpenProperty();
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int SetProps(uint values, IntPtr propArray, IntPtr problems);
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int DeleteProps();
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int CopyTo();
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int CopyProps();
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int GetNamesFromIDs();
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int GetIDsFromNames();
+ }
+
+ [StructLayout(LayoutKind.Explicit)]
+ private struct SPropValue {
+ [FieldOffset(0)]
+ public uint propTag;
+ [FieldOffset(4)]
+ public uint alignPad;
+ [FieldOffset(8)]
+ public IntPtr Value;
+ [FieldOffset(8)]
+ public long filler;
+ }
+
+ ///
+ /// Use MAPI32.DLL "HrGetOneProp" from managed code
+ ///
+ ///
+ ///
+ ///
+ public static string GetMAPIProperty(Attachment attachment, PropTags proptag) {
+ object mapiObject = attachment.MAPIOBJECT;
+ if (mapiObject == null) {
+ return "";
+ }
+
+ string sProperty = "";
+ IntPtr pPropValue = IntPtr.Zero;
+
+ IntPtr IUnknown = IntPtr.Zero;
+ IntPtr IMAPIProperty = IntPtr.Zero;
+
+ try {
+ MAPIInitialize(IntPtr.Zero);
+ IUnknown = Marshal.GetIUnknownForObject(mapiObject);
+ Guid guidMAPIProp = new Guid(IID_IMAPIProp);
+ if (Marshal.QueryInterface(IUnknown, ref guidMAPIProp, out IMAPIProperty) != 0) {
+ return "";
+ }
+ try {
+ HrGetOneProp(IMAPIProperty, (uint)proptag, out pPropValue);
+ if (pPropValue == IntPtr.Zero) {
+ return "";
+ }
+ SPropValue propValue = (SPropValue)Marshal.PtrToStructure(pPropValue, typeof(SPropValue));
+ sProperty = Marshal.PtrToStringUni(propValue.Value);
+ } catch (System.Exception ex) {
+ throw ex;
+ }
+ } finally {
+ if (pPropValue != IntPtr.Zero) {
+ MAPIFreeBuffer(pPropValue);
+ }
+ if (IMAPIProperty != IntPtr.Zero) {
+ Marshal.Release(IMAPIProperty);
+ }
+ if (IUnknown != IntPtr.Zero) {
+ Marshal.Release(IUnknown);
+ }
+ MAPIUninitialize();
+ }
+ return sProperty;
+ }
+
+ ///
+ /// Tries to save the changes we just made
+ ///
+ ///
+ ///
+ public static bool SaveChanges(MailItem mailItem) {
+ // Pointer to IUnknown Interface
+ IntPtr IUnknown = IntPtr.Zero;
+ // Pointer to IMAPIProp Interface
+ IntPtr IMAPIProp = IntPtr.Zero;
+ // if we have no MAPIObject everything is senseless...
+ if (mailItem == null) {
+ return false;
+ }
+
+ try {
+ // We can pass NULL here as parameter, so we do it.
+ MAPIInitialize(IntPtr.Zero);
+ // retrive the IUnknon Interface from our MAPIObject comming from Outlook.
+ IUnknown = Marshal.GetIUnknownForObject(mailItem.MAPIOBJECT);
+
+ // create a Guid that we pass to retreive the IMAPIProp Interface.
+ Guid guidIMAPIProp = new Guid(IID_IMAPIProp);
+
+ // try to retrieve the IMAPIProp interface from IMessage Interface, everything else is sensless.
+ if (Marshal.QueryInterface(IUnknown, ref guidIMAPIProp, out IMAPIProp) != 0) {
+ return false;
+ }
+ IMAPIProp mapiProp = (IMAPIProp)Marshal.GetTypedObjectForIUnknown(IUnknown, typeof(IMAPIProp));
+ return (mapiProp.SaveChanges(KEEP_OPEN_READWRITE) == 0);
+ } catch (Exception ex) {
+ LOG.Error(ex);
+ return false;
+ } finally {
+ // cleanup all references to COM Objects
+ if (IMAPIProp != IntPtr.Zero) Marshal.Release(IMAPIProp);
+ //if (IMessage != IntPtr.Zero) Marshal.Release(IMessage);
+ if (IUnknown != IntPtr.Zero) Marshal.Release(IUnknown);
+ }
+ }
+
+ ///
+ /// Uses the IMAPIPROP.SetProps to set the content ID
+ ///
+ ///
+ ///
+ public static void SetContentID(Attachment attachment, string contentId) {
+ // Pointer to IUnknown Interface
+ IntPtr IUnknown = IntPtr.Zero;
+ // Pointer to IMAPIProp Interface
+ IntPtr IMAPIProp = IntPtr.Zero;
+ // A pointer that points to the SPropValue structure
+ IntPtr ptrPropValue = IntPtr.Zero;
+ // Structure that will hold the Property Value
+ SPropValue propValue;
+ // if we have no MAPIObject everything is senseless...
+ if (attachment == null) {
+ return;
+ }
+
+ try {
+ // We can pass NULL here as parameter, so we do it.
+ MAPIInitialize(IntPtr.Zero);
+
+ // retrive the IUnknon Interface from our MAPIObject comming from Outlook.
+ IUnknown = Marshal.GetIUnknownForObject(attachment.MAPIOBJECT);
+ IMAPIProp mapiProp = (IMAPIProp)Marshal.GetTypedObjectForIUnknown(IUnknown, typeof(IMAPIProp));
+
+ // Create structure
+ propValue = new SPropValue();
+ propValue.propTag = (uint)PropTags.PR_ATTACH_CONTENT_ID;
+ //propValue.propTag = 0x3712001E;
+ // Create Ansi string
+ propValue.Value = Marshal.StringToHGlobalUni(contentId);
+
+ // Create unmanaged memory for structure
+ ptrPropValue = Marshal.AllocHGlobal(Marshal.SizeOf(propValue));
+ // Copy structure to unmanged memory
+ Marshal.StructureToPtr(propValue, ptrPropValue, false);
+ mapiProp.SetProps(1, ptrPropValue, IntPtr.Zero);
+
+ propValue.propTag = (uint)PropTags.PR_ATTACH_CONTENT_LOCATION;
+ // Copy structure to unmanged memory
+ Marshal.StructureToPtr(propValue, ptrPropValue, false);
+ mapiProp.SetProps(1, ptrPropValue, IntPtr.Zero);
+
+
+ // Free string
+ Marshal.FreeHGlobal(propValue.Value);
+ mapiProp.SaveChanges(KEEP_OPEN_READWRITE);
+ } catch (Exception ex) {
+ LOG.Error(ex);
+ } finally {
+ // Free used Memory structures
+ if (ptrPropValue != IntPtr.Zero) Marshal.FreeHGlobal(ptrPropValue);
+ // cleanup all references to COM Objects
+ if (IMAPIProp != IntPtr.Zero) Marshal.Release(IMAPIProp);
+ //if (IMessage != IntPtr.Zero) Marshal.Release(IMessage);
+ if (IUnknown != IntPtr.Zero) Marshal.Release(IUnknown);
+ }
+ }
+
+ ///
+ /// Use MAPI32.DLL "HrSetOneProp" from managed code
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static bool SetMAPIProperty(Attachment attachment, PropTags proptag, string propertyValue) {
+ // Pointer to IUnknown Interface
+ IntPtr IUnknown = IntPtr.Zero;
+ // Pointer to IMAPIProp Interface
+ IntPtr IMAPIProp = IntPtr.Zero;
+ // Structure that will hold the Property Value
+ SPropValue propValue;
+ // A pointer that points to the SPropValue structure
+ IntPtr ptrPropValue = IntPtr.Zero;
+ object mapiObject = attachment.MAPIOBJECT;
+ // if we have no MAPIObject everything is senseless...
+ if (mapiObject == null) {
+ return false;
+ }
+
+ try {
+ // We can pass NULL here as parameter, so we do it.
+ MAPIInitialize(IntPtr.Zero);
+
+ // retrive the IUnknon Interface from our MAPIObject comming from Outlook.
+ IUnknown = Marshal.GetIUnknownForObject(mapiObject);
+
+ // create a Guid that we pass to retreive the IMAPIProp Interface.
+ Guid guidIMAPIProp = new Guid(IID_IMAPIProp);
+
+ // try to retrieve the IMAPIProp interface from IMessage Interface, everything else is sensless.
+ if (Marshal.QueryInterface(IUnknown, ref guidIMAPIProp, out IMAPIProp) != 0) {
+ return false;
+ }
+
+ // double check, if we wave no pointer, exit...
+ if (IMAPIProp == IntPtr.Zero) {
+ return false;
+ }
+
+ // Create structure
+ propValue = new SPropValue();
+ propValue.propTag = (uint)proptag;
+ // Create Ansi string
+ propValue.Value = Marshal.StringToHGlobalUni(propertyValue);
+
+ // Create unmanaged memory for structure
+ ptrPropValue = Marshal.AllocHGlobal(Marshal.SizeOf(propValue));
+ // Copy structure to unmanged memory
+ Marshal.StructureToPtr(propValue, ptrPropValue, false);
+
+ // Set the property
+ HrSetOneProp(IMAPIProp, ptrPropValue);
+
+ // Free string
+ Marshal.FreeHGlobal(propValue.Value);
+ IMAPIProp mapiProp = (IMAPIProp)Marshal.GetTypedObjectForIUnknown(IUnknown, typeof(IMAPIProp));
+ return mapiProp.SaveChanges(4) == 0;
+ } catch (System.Exception ex) {
+ LOG.Error(ex);
+ return false;
+ } finally {
+ // Free used Memory structures
+ if (ptrPropValue != IntPtr.Zero) Marshal.FreeHGlobal(ptrPropValue);
+ // cleanup all references to COM Objects
+ if (IMAPIProp != IntPtr.Zero) Marshal.Release(IMAPIProp);
+ //if (IMessage != IntPtr.Zero) Marshal.Release(IMessage);
+ if (IUnknown != IntPtr.Zero) Marshal.Release(IUnknown);
+ MAPIUninitialize();
+ }
+ }
+
+ #region MAPI DLL Imports
+
+ [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi, EntryPoint = "HrGetOneProp@12")]
+ private static extern void HrGetOneProp(IntPtr pmp, uint ulPropTag, out IntPtr ppProp);
+
+ [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi, EntryPoint = "HrSetOneProp@8")]
+ private static extern void HrSetOneProp(IntPtr pmp, IntPtr pprop);
+
+ [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi, EntryPoint = "MAPIFreeBuffer@4")]
+ private static extern void MAPIFreeBuffer(IntPtr lpBuffer);
+
+ [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
+ private static extern int MAPIInitialize(IntPtr lpMapiInit);
+
+ [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
+ private static extern void MAPIUninitialize();
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/GreenshotOfficePlugin/OfficeInterop/PowerpointInterop.cs b/GreenshotOfficePlugin/OfficeInterop/PowerpointInterop.cs
new file mode 100644
index 000000000..41f81f3a8
--- /dev/null
+++ b/GreenshotOfficePlugin/OfficeInterop/PowerpointInterop.cs
@@ -0,0 +1,149 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+using System.Collections;
+
+namespace Greenshot.Interop.Office {
+ // See http://msdn.microsoft.com/en-us/library/microsoft.office.interop.powerpoint.application_members.aspx
+ [ComProgId("Powerpoint.Application")]
+ public interface IPowerpointApplication : Common {
+ IPresentation ActivePresentation { get; }
+ IPresentations Presentations { get; }
+ bool Visible { get; set; }
+ void Activate();
+ IPowerpointWindow ActiveWindow { get; }
+ string Version { get; }
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.powerpoint.slides_members.aspx
+ public interface ISlides : Common {
+ int Count { get; }
+ ISlide Add(int Index, int layout);
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.powerpoint.documentwindow.view.aspx
+ public interface IPowerpointWindow : Common {
+ void Activate();
+ IPowerpointView View { get; }
+ }
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.powerpoint.view_members.aspx
+ public interface IPowerpointView : Common {
+ IZoom Zoom { get; }
+ void GotoSlide(int index);
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.powerpoint.presentation_members.aspx
+ public interface IPresentation : Common {
+ string Name { get; }
+ ISlides Slides { get; }
+ IPowerpointApplication Application { get; }
+ MsoTriState ReadOnly { get; }
+ bool Final { get; set; }
+ IPageSetup PageSetup { get; }
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.powerpoint.presentations_members.aspx
+ public interface IPresentations : Common, Collection {
+ IPresentation Add(MsoTriState WithWindow);
+ IPresentation item(int index);
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.powerpoint.pagesetup_members.aspx
+ public interface IPageSetup : Common, Collection {
+ float SlideWidth { get; set; }
+ float SlideHeight { get; set; }
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.powerpoint.slide_members.aspx
+ public interface ISlide : Common {
+ IShapes Shapes { get; }
+ void Select();
+ int SlideNumber { get; }
+
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.powerpoint.shapes_members.aspx
+ public interface IShapes : Common, IEnumerable {
+ int Count { get; }
+ IShape item(int index);
+ IShape AddPicture(string FileName, MsoTriState LinkToFile, MsoTriState SaveWithDocument, float Left, float Top, float Width, float Height);
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.powerpoint.shape_members.aspx
+ public interface IShape : Common {
+ float Left { get; set; }
+ float Top { get; set; }
+ float Width { get; set; }
+ float Height { get; set; }
+ ITextFrame TextFrame { get; }
+ void ScaleWidth(float Factor, MsoTriState RelativeToOriginalSize, MsoScaleFrom fScale);
+ void ScaleHeight(float Factor, MsoTriState RelativeToOriginalSize, MsoScaleFrom fScale);
+ string AlternativeText { get; set; }
+ MsoTriState LockAspectRatio { get; set; }
+ }
+
+ public interface ITextFrame : Common {
+ ITextRange TextRange { get; }
+ MsoTriState HasText { get; }
+ }
+ public interface ITextRange : Common {
+ string Text { get; set; }
+ }
+
+ public enum PPSlideLayout : int {
+ ppLayoutMixed = -2,
+ ppLayoutTitle = 1,
+ ppLayoutText = 2,
+ ppLayoutTwoColumnText = 3,
+ ppLayoutTable = 4,
+ ppLayoutTextAndChart = 5,
+ ppLayoutChartAndText = 6,
+ ppLayoutOrgchart = 7,
+ ppLayoutChart = 8,
+ ppLayoutTextAndClipart = 9,
+ ppLayoutClipartAndText = 10,
+ ppLayoutTitleOnly = 11,
+ ppLayoutBlank = 12,
+ ppLayoutTextAndObject = 13,
+ ppLayoutObjectAndText = 14,
+ ppLayoutLargeObject = 15,
+ ppLayoutObject = 16,
+ ppLayoutTextAndMediaClip = 17,
+ ppLayoutMediaClipAndText = 18,
+ ppLayoutObjectOverText = 19,
+ ppLayoutTextOverObject = 20,
+ ppLayoutTextAndTwoObjects = 21,
+ ppLayoutTwoObjectsAndText = 22,
+ ppLayoutTwoObjectsOverText = 23,
+ ppLayoutFourObjects = 24,
+ ppLayoutVerticalText = 25,
+ ppLayoutClipArtAndVerticalText = 26,
+ ppLayoutVerticalTitleAndText = 27,
+ ppLayoutVerticalTitleAndTextOverChart = 28,
+ ppLayoutTwoObjects = 29,
+ ppLayoutObjectAndTwoObjects = 30,
+ ppLayoutTwoObjectsAndObject = 31,
+ ppLayoutCustom = 32,
+ ppLayoutSectionHeader = 33,
+ ppLayoutComparison = 34,
+ ppLayoutContentWithCaption = 35,
+ ppLayoutPictureWithCaption = 36
+ }
+}
diff --git a/GreenshotOfficePlugin/OfficeInterop/WordInterop.cs b/GreenshotOfficePlugin/OfficeInterop/WordInterop.cs
new file mode 100644
index 000000000..31745f300
--- /dev/null
+++ b/GreenshotOfficePlugin/OfficeInterop/WordInterop.cs
@@ -0,0 +1,84 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+namespace Greenshot.Interop.Office {
+ // See http://msdn.microsoft.com/de-de/library/microsoft.office.interop.word.applicationclass_members%28v=Office.11%29.aspx
+ [ComProgId("Word.Application")]
+ public interface IWordApplication : Common {
+ IWordDocument ActiveDocument { get; }
+ ISelection Selection { get; }
+ IDocuments Documents { get; }
+ bool Visible { get; set; }
+ void Activate();
+ string Version { get; }
+ }
+
+ // See: http://msdn.microsoft.com/de-de/library/microsoft.office.interop.word.documents_members(v=office.11).aspx
+ public interface IDocuments : Common, Collection {
+ IWordDocument Add(ref object Template, ref object NewTemplate, ref object DocumentType, ref object Visible);
+ IWordDocument item(int index);
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.document.aspx
+ public interface IWordDocument : Common {
+ void Activate();
+ IWordApplication Application { get; }
+ IWordWindow ActiveWindow { get; }
+ bool ReadOnly { get; }
+
+ // Only 2007 and later!
+ bool Final { get; set; }
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.window_members.aspx
+ public interface IWordWindow : Common {
+ IPane ActivePane { get; }
+ void Activate();
+ string Caption {
+ get;
+ }
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.pane_members.aspx
+ public interface IPane : Common {
+ IWordView View { get; }
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.view_members.aspx
+ public interface IWordView : Common {
+ IZoom Zoom { get; }
+ }
+
+ // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.zoom_members.aspx
+ public interface IZoom : Common {
+ int Percentage { get; set; }
+ }
+
+ // See: http://msdn.microsoft.com/de-de/library/microsoft.office.interop.word.selection_members(v=office.11).aspx
+ public interface ISelection : Common {
+ IInlineShapes InlineShapes { get; }
+ void InsertAfter(string text);
+ }
+
+ public interface IInlineShapes : Common {
+ object AddPicture(string FileName, object LinkToFile, object SaveWithDocument, object Range);
+ }
+}