예제 #1
0
        /// <summary>
        ///     Wrap an object and return the transparent proxy which intercepts all calls to the object
        /// </summary>
        /// <param name="comObject">An object to intercept</param>
        /// <param name="type">Interface which defines the method and properties to intercept</param>
        /// <param name="targetName"></param>
        /// <returns>Transparent proxy to the real proxy for the object</returns>
        private static object Wrap(object comObject, Type type, string targetName)
        {
            if (null == comObject)
            {
                throw new ArgumentNullException(nameof(comObject));
            }
            if (null == type)
            {
                throw new ArgumentNullException(nameof(type));
            }

            var wrapper = new ComWrapper(comObject, type, targetName);

            return(wrapper.GetTransparentProxy());
        }
예제 #2
0
        /// <summary>
        ///     Wrap a com object as COMWrapper
        /// </summary>
        /// <typeparam name="T">Interface which defines the method and properties to intercept</typeparam>
        /// <param name="comObject">An object to intercept</param>
        /// <returns>Transparent proxy to the real proxy for the object</returns>
        public static T Wrap <T>(object comObject)
        {
            var type = typeof(T);

            if (null == comObject)
            {
                throw new ArgumentNullException(nameof(comObject));
            }
            if (null == type)
            {
                throw new ArgumentNullException(nameof(T));
            }

            var wrapper = new ComWrapper(comObject, type, type.FullName);

            return((T)wrapper.GetTransparentProxy());
        }
예제 #3
0
        /// <summary>
        ///     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:"
        /// </summary>
        /// <typeparam name="T">Interface which defines the method and properties to intercept</typeparam>
        /// <returns>Transparent proxy to the real proxy for the object</returns>
        /// <remarks>T must be an interface decorated with the <see cref="ComProgIdAttribute" />attribute.</remarks>
        public static T GetOrCreateInstance <T>()
        {
            var type = typeof(T);

            if (null == type)
            {
                throw new ArgumentNullException(nameof(T));
            }
            if (!type.IsInterface)
            {
                throw new ArgumentException("The specified type must be an interface.", nameof(T));
            }

            var progIdAttribute = ComProgIdAttribute.GetAttribute(type);

            if (string.IsNullOrEmpty(progIdAttribute?.Value))
            {
                throw new ArgumentException("The specified type must define a ComProgId attribute.", nameof(T));
            }

            object comObject = null;
            Type   comType   = null;
            var    progId    = progIdAttribute.Value;
            var    guid      = Guid.Empty;

            // Convert from clsid to Prog ID, if needed
            if (progId.StartsWith("clsid:"))
            {
                guid = new Guid(progId.Substring(6));
                var result = ProgIDFromCLSID(ref guid, out progId);
                if (result != 0)
                {
                    // Restore progId, as it's overwritten
                    progId = progIdAttribute.Value;
                    try
                    {
                        GetActiveObject(ref guid, IntPtr.Zero, out comObject);
                    }
                    catch (Exception)
                    {
                        Log.Warn().WriteLine("Error {0} getting instance for class id {1}", result, progIdAttribute.Value);
                    }
                    if (comObject == null)
                    {
                        Log.Warn().WriteLine("Error {0} getting progId {1}", result, progIdAttribute.Value);
                    }
                }
                else
                {
                    Log.Info().WriteLine("Mapped {0} to progId {1}", progIdAttribute.Value, progId);
                }
            }

            if (comObject == null && !progId.StartsWith("clsid:"))
            {
                try
                {
                    comObject = Marshal.GetActiveObject(progId);
                }
                catch (COMException comE)
                {
                    if (comE.ErrorCode == MK_E_UNAVAILABLE)
                    {
                        Log.Debug().WriteLine("No current instance of {0} object available.", progId);
                    }
                    else if (comE.ErrorCode == CO_E_CLASSSTRING)
                    {
                        Log.Warn().WriteLine("Unknown progId {0} (application not installed)", progId);
                        return(default(T));
                    }
                    else
                    {
                        Log.Warn().WriteLine(comE, "Error getting active object for " + progId);
                    }
                }
                catch (Exception e)
                {
                    Log.Warn().WriteLine(e, "Error getting active object for " + progId);
                }
            }

            // Did we get the current instance? If not, try to create a new
            if (comObject == null)
            {
                try
                {
                    comType = Type.GetTypeFromProgID(progId, true);
                }
                catch (Exception ex)
                {
                    if (Guid.Empty != guid)
                    {
                        comType = Type.GetTypeFromCLSID(guid);
                    }
                    else
                    {
                        Log.Warn().WriteLine(ex, "Error type for " + progId);
                    }
                }

                if (comType != null)
                {
                    try
                    {
                        comObject = Activator.CreateInstance(comType);
                        if (comObject != null)
                        {
                            Log.Debug().WriteLine("Created new instance of {0} object.", progId);
                        }
                    }
                    catch (Exception e)
                    {
                        Log.Warn().WriteLine(e, "Error creating object for " + progId);
                    }
                }
            }
            if (comObject != null)
            {
                if (comObject is IDispatch)
                {
                    var wrapper = new ComWrapper(comObject, type, progIdAttribute.Value);
                    return((T)wrapper.GetTransparentProxy());
                }
                return((T)comObject);
            }
            return(default(T));
        }