diff --git a/GreenshotInterop/GreenshotInterop.csproj b/GreenshotInterop/GreenshotInterop.csproj
index d29125004..775330ba1 100644
--- a/GreenshotInterop/GreenshotInterop.csproj
+++ b/GreenshotInterop/GreenshotInterop.csproj
@@ -22,6 +22,8 @@
DEBUG;TRACE
prompt
4
+ 3
+ false
pdbonly
@@ -30,8 +32,12 @@
TRACE
prompt
4
+ Off
+ 3
+ false
+
..\Greenshot\Lib\log4net.dll
@@ -40,6 +46,8 @@
+
+
@@ -61,6 +69,8 @@
+
+
diff --git a/GreenshotInterop/Interop/COMWrapper.cs b/GreenshotInterop/Interop/COMWrapper.cs
index 1b9b83c49..9f03448f3 100644
--- a/GreenshotInterop/Interop/COMWrapper.cs
+++ b/GreenshotInterop/Interop/COMWrapper.cs
@@ -29,7 +29,7 @@ namespace Greenshot.Interop {
///
/// Wraps a late-bound COM server.
///
- public sealed class COMWrapper : RealProxy, IDisposable {
+ public sealed class COMWrapper : RealProxy, IDisposable, IRemotingTypeInfo {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(COMWrapper));
private const int MK_E_UNAVAILABLE = -2147221021;
#region Private Data
@@ -95,8 +95,8 @@ namespace Greenshot.Interop {
}
///
- /// Gets or creates a COM object and returns the transparent proxy
- /// which intercepts all calls to the object
+ /// Gets or creates a COM object and returns the transparent proxy which intercepts all calls to the object
+ /// The ComProgId can be a normal ComProgId or a GUID prefixed with "clsid:"
///
/// Interface which defines the method and properties to intercept
/// Transparent proxy to the real proxy for the object
@@ -116,7 +116,13 @@ namespace Greenshot.Interop {
}
object comObject = null;
- Type comType = Type.GetTypeFromProgID(progID.Value, true);
+ Type comType = null;
+ if (progID.Value.StartsWith("clsid:")) {
+ Guid guid = new Guid(progID.Value.Substring(6));
+ comType = Type.GetTypeFromCLSID(guid, true);
+ } else {
+ comType = Type.GetTypeFromProgID(progID.Value, true);
+ }
try {
comObject = Marshal.GetActiveObject(progID.Value);
} catch (COMException comE) {
@@ -294,14 +300,84 @@ namespace Greenshot.Interop {
#endregion
+ ///
+ /// Use this static method to cast a wrapped proxy to a new wrapper proxy of the supplied type.
+ /// In English, use this to cast you base "COM" interface to a specialized interface.
+ /// E.G. Outlook Item -> MailItem
+ ///
+ /// the type you want to cast to
+ /// The wrapper interface, e.g. something you got back from calling GetItem
+ /// A new wrapper proxy for the specified type
public static T Cast(object wrapperProxy) {
if (wrapperProxy == null) {
return default(T);
}
+
Type newType = typeof(T);
COMWrapper oldWrapper = RemotingServices.GetRealProxy(wrapperProxy) as COMWrapper;
- COMWrapper newWrapper = new COMWrapper(oldWrapper._COMObject, newType);
- return (T)newWrapper.GetTransparentProxy();
+ if (oldWrapper == null) {
+ throw new ArgumentException("wrapper proxy was no COMWrapper");
+ }
+ if (oldWrapper._InterceptType.IsAssignableFrom(newType)) {
+ COMWrapper newWrapper = new COMWrapper(oldWrapper._COMObject, newType);
+ return (T)newWrapper.GetTransparentProxy();
+ }
+ throw new InvalidCastException(string.Format("{0} is not assignable from {1}", oldWrapper._InterceptType, newType));
+ }
+
+ ///
+ /// Returns the "com" type of the wrapperproxy, making it possible to perform reflection on it.
+ ///
+ /// wrapperProxy to get the type from
+ /// Type
+ public static Type GetUnderlyingType(object wrapperProxy) {
+ Type returnType = null;
+ COMWrapper wrapper = RemotingServices.GetRealProxy(wrapperProxy) as COMWrapper;
+ if (wrapper != null) {
+ IDispatch dispatch = wrapper._COMObject as IDispatch;
+ if (dispatch != null) {
+ int result = dispatch.GetTypeInfo(0, 0, out returnType);
+ if (result != 0) {
+ LOG.DebugFormat("GetTypeInfo : 0x{0} ({1})", result.ToString("X"), result);
+ }
+ }
+ }
+ return returnType;
+ }
+
+ ///
+ /// Dump the Type-Information for the COM type to the log, this uses reflection
+ ///
+ /// wrapperProxy to inspect
+ public static void DumpTypeInfo(object wrapperProxy) {
+ Type comType = COMWrapper.GetUnderlyingType(wrapperProxy);
+ if (comType == null) {
+ LOG.InfoFormat("Can't get Typeinformation");
+ return;
+ }
+ LOG.InfoFormat("Type information for COM object with name: {0}", comType.Name);
+ try {
+ foreach (MemberInfo memberInfo in comType.GetMembers()) {
+ LOG.InfoFormat("Member: {0};", memberInfo.ToString());
+ }
+ } catch (Exception memberException) {
+ LOG.Error(memberException);
+ }
+ try {
+ foreach (PropertyInfo propertyInfo in comType.GetProperties()) {
+ LOG.InfoFormat("Property: {0};", propertyInfo.ToString());
+ }
+ } catch (Exception propertyException) {
+ LOG.Error(propertyException);
+ }
+ try {
+ foreach (FieldInfo fieldInfo in comType.GetFields()) {
+ LOG.InfoFormat("Field: {0};", fieldInfo.ToString());
+ }
+ } catch (Exception fieldException) {
+ LOG.Error(fieldException);
+ }
+ LOG.InfoFormat("Type information end.");
}
///
@@ -497,5 +573,29 @@ namespace Greenshot.Interop {
return new ReturnMessage(returnValue, outArgs, outArgsCount, callMessage.LogicalCallContext, callMessage);
}
+
+ ///
+ /// Implementation for the interface IRemotingTypeInfo
+ /// This makes it possible to cast the COMWrapper
+ ///
+ /// Type to cast to
+ /// object to cast
+ ///
+ public bool CanCastTo(Type toType, object o) {
+ bool returnValue = _InterceptType.IsAssignableFrom(toType);
+ return returnValue;
+ }
+
+ ///
+ /// Implementation for the interface IRemotingTypeInfo
+ ///
+ public string TypeName {
+ get {
+ throw new NotImplementedException();
+ }
+ set {
+ throw new NotImplementedException();
+ }
+ }
}
}
diff --git a/GreenshotInterop/OfficeExport/OutlookEmailExporter.cs b/GreenshotInterop/OfficeExport/OutlookEmailExporter.cs
index 5292aa3c5..0741c7b9a 100644
--- a/GreenshotInterop/OfficeExport/OutlookEmailExporter.cs
+++ b/GreenshotInterop/OfficeExport/OutlookEmailExporter.cs
@@ -89,12 +89,15 @@ namespace Greenshot.Interop.Office {
if (currentItem != null) {
OlObjectClass currentItemClass = currentItem.Class;
if (OlObjectClass.olMail.Equals(currentItemClass)) {
- MailItem mailItem = COMWrapper.Cast(currentItem);
+ 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 >= 12 && allowMeetingAsTarget && OlObjectClass.olAppointment.Equals(currentItemClass)) {
- AppointmentItem appointmentItem = COMWrapper.Cast(currentItem);
+ //AppointmentItem appointmentItem = COMWrapper.Cast(currentItem);
+ AppointmentItem appointmentItem = (AppointmentItem)currentItem;
if (string.IsNullOrEmpty(appointmentItem.Organizer) || (currentUser == null && currentUser.Equals(appointmentItem.Organizer))) {
return true;
} else {
@@ -166,7 +169,8 @@ namespace Greenshot.Interop.Office {
MailItem mailItem = null;
try {
if (isMail) {
- mailItem = COMWrapper.Cast(currentItem);
+ //mailItem = COMWrapper.Cast(currentItem);
+ mailItem = (MailItem)currentItem;
if (mailItem.Sent) {
LOG.WarnFormat("Item already sent, can't export to {0}", currentItem.Subject);
return false;
@@ -271,7 +275,8 @@ namespace Greenshot.Interop.Office {
if (newItem == null) {
return;
}
- MailItem newMail = COMWrapper.Cast(newItem);
+ //MailItem newMail = COMWrapper.Cast(newItem);
+ MailItem newMail = (MailItem)newItem;
newMail.Subject = subject;
newMail.BodyFormat = OlBodyFormat.olFormatHTML;
string bodyString = null;
diff --git a/GreenshotInterop/OfficeInterop/ExcelInterop.cs b/GreenshotInterop/OfficeInterop/ExcelInterop.cs
index 7d44e4756..391abdb49 100644
--- a/GreenshotInterop/OfficeInterop/ExcelInterop.cs
+++ b/GreenshotInterop/OfficeInterop/ExcelInterop.cs
@@ -36,6 +36,7 @@ namespace Greenshot.Interop.Office {
// 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; }
}
@@ -55,10 +56,13 @@ namespace Greenshot.Interop.Office {
// See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.iworksheets_members.aspx
public interface IWorksheets : Common, Collection {
- Object this[object Index] { get; }
+ // 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/GreenshotInterop/OfficeInterop/OfficeInterop.cs b/GreenshotInterop/OfficeInterop/OfficeInterop.cs
index 4e379daa6..545832238 100644
--- a/GreenshotInterop/OfficeInterop/OfficeInterop.cs
+++ b/GreenshotInterop/OfficeInterop/OfficeInterop.cs
@@ -23,11 +23,8 @@ using System.Collections;
namespace Greenshot.Interop.Office {
///
- /// Common properties that has appreared in almost all objects
+ /// If the "type" this[object index] { get; } is implemented, use index + 1!!! (starts at 1)
///
- public interface Common : IDisposable {
- }
-
public interface Collection : Common, IEnumerable {
int Count { get; }
void Remove(int index);
@@ -81,6 +78,7 @@ namespace Greenshot.Interop.Office {
}
// 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; }
@@ -93,6 +91,7 @@ namespace Greenshot.Interop.Office {
}
// 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; }
@@ -102,8 +101,28 @@ namespace Greenshot.Interop.Office {
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
@@ -113,6 +132,7 @@ namespace Greenshot.Interop.Office {
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
diff --git a/GreenshotInterop/OfficeInterop/OutlookInterop.cs b/GreenshotInterop/OfficeInterop/OutlookInterop.cs
index b46667ba2..d7ba6bc47 100644
--- a/GreenshotInterop/OfficeInterop/OutlookInterop.cs
+++ b/GreenshotInterop/OfficeInterop/OutlookInterop.cs
@@ -86,6 +86,7 @@ namespace Greenshot.Interop.Office {
// 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; }
}