コード例 #1
0
ファイル: MemberFactory.cs プロジェクト: alexhelms/ASCOM.Core
        /// <summary>
        /// Calls a method on an object dynamically.
        ///
        /// parameterTypes must match the parameters and in the same order.
        /// </summary>
        /// <param name="memberCode">1-GetProperty, 2-SetProperty, 3-Method</param>
        /// <param name="memberName">The member name to call as a string</param>
        /// <param name="parameterTypes">Array of paramerter types in order</param>
        /// <param name="parms">Array of parameters in order</param>
        /// <exception cref="PropertyNotImplementedException"></exception>
        /// <exception cref="MethodNotImplementedException"></exception>
        /// <returns>object</returns>
        internal object CallMember(int memberCode, string memberName, Type[] parameterTypes, params object[] parms)
        {
            TL.BlankLine();
            switch (memberCode)
            {
            case 1:                          // Property Read
                PropertyInfo propertyGetInfo = GetObjType.GetProperty(memberName);
                if (propertyGetInfo != null) // We have a .NET object
                {
                    TL.LogMessage(memberName + " Get", "GET " + memberName + " - .NET");
                    try
                    {
                        //run the .net object
                        object result = propertyGetInfo.GetValue(GetLateBoundObject, null);
                        TL.LogMessage(memberName + " Get", "  " + result.ToString());
                        return(result);
                    }
                    catch (TargetInvocationException e)
                    {
                        GetTargetInvocationExceptionHandler(memberName, e);
                    }
                    catch (Exception e)
                    {
                        TL.LogMessageCrLf("Exception", e.ToString());
                        throw;
                    }
                }

                //check the type to see if it's a COM object
                if (IsComObject)     // We have a COM object
                {
                    TL.LogMessage(memberName + " Get", "GET " + memberName + " - COM");

                    try
                    {
                        //run the COM object property
                        object result = GetObjType.InvokeMember(memberName,
                                                                BindingFlags.Default | BindingFlags.GetProperty,
                                                                null,
                                                                GetLateBoundObject,
                                                                new object[] { },
                                                                CultureInfo.InvariantCulture);
                        TL.LogMessage(memberName + " Get", "  " + result.ToString());
                        return(result);
                    }
                    catch (COMException e)
                    {
                        TL.LogMessageCrLf("COMException", e.ToString());
                        if (e.ErrorCode == int.Parse("80020006", NumberStyles.HexNumber, CultureInfo.InvariantCulture))
                        {
                            TL.LogMessageCrLf(memberName + " Get", "  Throwing PropertyNotImplementedException: " + _strProgId + " " + memberName);
                            throw new PropertyNotImplementedException(_strProgId + " " + memberName, false, e);
                        }
                        TL.LogMessageCrLf(memberName + " Get", "Re-throwing exception");
                        throw;
                    }
                    catch (TargetInvocationException e)
                    {
                        TL.LogMessageCrLf("TargetInvocationException", e.ToString());
                        if (e.InnerException is COMException)
                        {
                            string message   = e.InnerException.Message;
                            int    errorcode = ((COMException)e.InnerException).ErrorCode;
                            // Telescope simulator in V1 mode throws not implemented exceptions rather than some kind of missing member exception, so test for this!
                            if (errorcode == int.Parse("80040400", NumberStyles.HexNumber, CultureInfo.InvariantCulture))
                            {
                                TL.LogMessageCrLf(memberName + " Get", "  Translating COM not implemented exception to PropertyNotImplementedException: " + _strProgId + " " + memberName);
                                throw new PropertyNotImplementedException(_strProgId + " " + memberName, false, e);
                            }
                            else     // Throw a new COM exception that looks like the original exception, containing the original inner COM exception for reference
                            {
                                TL.LogMessageCrLf(memberName + " Get", "COM Exception so throwing inner exception: '" + message + "' '0x" + String.Format("{0:x8}", errorcode) + "'");
                                throw new DriverAccessCOMException(message, errorcode, e);
                            }
                        }

                        GetTargetInvocationExceptionHandler(memberName, e);
                    }

                    catch (Exception e)
                    {
                        TL.LogMessageCrLf("Exception", e.ToString());
                        throw;
                    }
                }

                //evertyhing failed so throw an exception
                TL.LogMessage(memberName + " Get", "  The object is neither a .NET object nor a COM object!");
                throw new PropertyNotImplementedException(_strProgId + " " + memberName, false);

            case 2:                          // Property Write
                PropertyInfo propertySetInfo = GetObjType.GetProperty(memberName);
                if (propertySetInfo != null) // We have a .NET object
                {
                    TL.LogMessage(memberName + " Set", "SET " + memberName + " - .NET");
                    try
                    {
                        TL.LogMessage(memberName + " Set", "  " + parms[0].ToString());
                        propertySetInfo.SetValue(GetLateBoundObject, parms[0], null);
                        return(null);
                    }
                    catch (TargetInvocationException e)
                    {
                        SetTargetInvocationExceptionHandler(memberName, e);
                    }
                    catch (Exception e)
                    {
                        TL.LogMessageCrLf("Exception", e.ToString());
                        throw;
                    }
                }

                //check the type to see if it's a COM object
                if (IsComObject)
                {
                    TL.LogMessage(memberName + " Set", "SET " + memberName + " - COM");

                    try
                    {
                        TL.LogMessage(memberName + " Set", "  " + parms[0].ToString());
                        //run the COM object property
                        GetObjType.InvokeMember(memberName,
                                                BindingFlags.Default | BindingFlags.SetProperty,
                                                null,
                                                GetLateBoundObject,
                                                parms,
                                                CultureInfo.InvariantCulture);
                        return(null);
                    }
                    catch (COMException e)
                    {
                        TL.LogMessageCrLf("COMException", e.ToString());
                        if (e.ErrorCode == int.Parse("80020006", NumberStyles.HexNumber, CultureInfo.InvariantCulture))
                        {
                            TL.LogMessageCrLf(memberName + " Set", "  Throwing PropertyNotImplementedException: " + _strProgId + " " + memberName);
                            throw new PropertyNotImplementedException(_strProgId + " " + memberName, true, e);
                        }
                        TL.LogMessageCrLf(memberName + " Set", "  Re-throwing exception");
                        throw;
                    }
                    catch (TargetInvocationException e)
                    {
                        TL.LogMessageCrLf("TargetInvocationException", e.ToString());

                        if (e.InnerException is COMException)
                        {
                            string message   = e.InnerException.Message;
                            int    errorcode = ((COMException)e.InnerException).ErrorCode;
                            // Telescope simulator in V1 mode throws not implemented exceptions rather than some kind of missing member exception, so test for this!
                            if (errorcode == int.Parse("80040400", NumberStyles.HexNumber, CultureInfo.InvariantCulture))
                            {
                                TL.LogMessageCrLf(memberName + " Set", "  Translating COM not implemented exception to PropertyNotImplementedException: " + _strProgId + " " + memberName);
                                throw new PropertyNotImplementedException(_strProgId + " " + memberName, true, e);
                            }
                            else     // Throw a new COM exception that looks like the original exception, containing the original inner COM exception for reference
                            {
                                TL.LogMessageCrLf(memberName + " Set", "COM Exception so throwing inner exception: '" + message + "' '0x" + String.Format("{0:x8}", errorcode) + "'");
                                throw new DriverAccessCOMException(message, errorcode, e);
                            }
                        }

                        SetTargetInvocationExceptionHandler(memberName, e);
                    }
                    catch (Exception e)
                    {
                        TL.LogMessageCrLf("Exception", e.ToString());
                        throw;
                    }
                }

                //evertyhing failed so throw an exception
                TL.LogMessage("PropertySet", "  The object is neither a .NET object nor a COM object!");
                throw new PropertyNotImplementedException(_strProgId + " " + memberName, true);

            case 3:     // Method
                TL.LogMessage(memberName, "Start");

                /*foreach (Type t in parameterTypes)
                 * {
                 *  TL.LogMessage(memberName, "  Parameter: " + t.FullName);
                 * }*/

                var methodInfo = GetObjType.GetMethod(memberName);
                //, parameterTypes); //Peter: Had to take parameterTypes out to get CanMoveAxis to work with .NET drivers
                if (methodInfo != null)
                {
                    //TL.LogMessage(memberName, "  Got MethodInfo");

                    //ParameterInfo[] pars = methodInfo.GetParameters();

                    /*foreach (ParameterInfo p in pars)
                     * {
                     *  TL.LogMessage(memberName, "    Parameter: " + p.ParameterType);
                     * } */

                    try
                    {
                        foreach (object parm in parms)
                        {
                            TL.LogMessage(memberName, "  Parameter: " + parm.ToString());
                        }
                        TL.LogMessage(memberName, "  Calling " + memberName);
                        object result = methodInfo.Invoke(GetLateBoundObject, parms);

                        if (result == null)
                        {
                            TL.LogMessage(memberName, "  Successfully called method, no return value");
                        }
                        else
                        {
                            TL.LogMessage(memberName, "  " + result.ToString());
                        }

                        return(result);
                    }
                    catch (TargetInvocationException e)
                    {
                        MethodTargetInvocationExceptionHandler(memberName, e);
                    }

                    // Unexpected exception so throw it all to the client
                    catch (Exception e)
                    {
                        TL.LogMessageCrLf("Exception", e.ToString());
                        throw;
                    }
                }

                //check the type to see if it's a COM object
                if (IsComObject)
                {
                    try
                    {
                        //run the COM object method
                        foreach (object parm in parms)
                        {
                            TL.LogMessage(memberName, "  Parameter: " + parm.ToString());
                        }
                        TL.LogMessage(memberName, "  Calling " + memberName + " - it is a COM object");
                        object result = GetObjType.InvokeMember(memberName,
                                                                BindingFlags.Default | BindingFlags.InvokeMethod,
                                                                null,
                                                                GetLateBoundObject,
                                                                parms,
                                                                CultureInfo.InvariantCulture);

                        if (result == null)
                        {
                            TL.LogMessage(memberName, "  Successfully called method, no return value");
                        }
                        else
                        {
                            TL.LogMessage(memberName, "  " + result.ToString());
                        }

                        return(result);
                    }
                    catch (COMException e)
                    {
                        TL.LogMessageCrLf("COMException", e.ToString());
                        if (e.ErrorCode == int.Parse("80020006", NumberStyles.HexNumber, CultureInfo.InvariantCulture))
                        {
                            TL.LogMessageCrLf(memberName, "  Throwing MethodNotImplementedException: " + _strProgId + " " + memberName);
                            throw new MethodNotImplementedException(_strProgId + " " + memberName);
                        }
                        TL.LogMessageCrLf(memberName, "Re-throwing exception");
                        throw;
                    }
                    catch (TargetInvocationException e)
                    {
                        TL.LogMessageCrLf("TargetInvocationException", e.ToString());
                        if (e.InnerException is COMException)
                        {
                            string message   = e.InnerException.Message;
                            int    errorcode = ((COMException)e.InnerException).ErrorCode;
                            // Telescope simulator in V1 mode throws not implemented exceptions rather than some kind of missing member exception, so test for this!
                            if (errorcode == int.Parse("80040400", NumberStyles.HexNumber, CultureInfo.InvariantCulture))
                            {
                                TL.LogMessageCrLf(memberName, "  Translating COM not implemented exception to MethodNotImplementedException: " + _strProgId + " " + memberName);
                                throw new MethodNotImplementedException(_strProgId + " " + memberName, e);
                            }
                            else     // Throw a new COM exception that looks like the original exception, containing the original inner COM exception for reference
                            {
                                TL.LogMessageCrLf(memberName, "  COM Exception so throwing inner exception: '" + message + "' '0x" + String.Format("{0:x8}", errorcode) + "'");
                                throw new DriverAccessCOMException(message, errorcode, e);
                            }
                        }

                        MethodTargetInvocationExceptionHandler(memberName, e);
                    }
                    catch (Exception e)
                    {
                        TL.LogMessageCrLf("Exception", e.ToString());
                        throw;
                    }
                }

                TL.LogMessage(memberName, "  is neither a .NET object nor a COM object!");
                throw new MethodNotImplementedException(_strProgId + " " + memberName);

            default:
                return(null);
            }
        }
コード例 #2
0
ファイル: MemberFactory.cs プロジェクト: alexhelms/ASCOM.Core
        /// <summary>
        /// Dispose the late-bound interface, if needed. Will release it via COM
        /// if it is a COM object, else if native .NET will just dereference it
        /// for GC.
        /// </summary>
        /// <returns>nothing</returns>
        public void Dispose()
        {
            if (GetLateBoundObject != null)
            {
                try
                {
                    if (IsComObject)
                    {
                        // Attempt to call Dispose first...

                        //run the COM object method
                        try
                        {
                            TL.LogMessageCrLf("Dispose COM", "This is a COM object, attempting to call its Dispose method");
                            GetObjType.InvokeMember("Dispose",
                                                    BindingFlags.Default | BindingFlags.InvokeMethod,
                                                    null,
                                                    GetLateBoundObject,
                                                    new object[] { },
                                                    CultureInfo.InvariantCulture);
                            TL.LogMessageCrLf("Dispose COM", "Successfully called its Dispose method");
                        }
                        catch (COMException ex)
                        {
                            if (ex.ErrorCode == int.Parse("80020006", NumberStyles.HexNumber, CultureInfo.InvariantCulture))
                            {
                                TL.LogMessageCrLf("Dispose COM", "Driver does not have a Dispose method");
                            }
                        }
                        catch (Exception ex)
                        {
                            TL.LogMessageCrLf("Dispose COM", "Exception " + ex.ToString());
                        }

                        TL.LogMessageCrLf("Dispose COM", "This is a COM object so attempting to release it");
                        var releaseComObject = Marshal.ReleaseComObject(GetLateBoundObject);
                        if (releaseComObject == 0)
                        {
                            GetLateBoundObject = null;
                        }
                        TL.LogMessageCrLf("Dispose COM", "Object Count is now: " + releaseComObject);
                    }
                    else // Should be a .NET object so lets dispose of it
                    {
                        TL.LogMessageCrLf("Dispose .NET", "This is a .NET object, attempting to call its Dispose method");
                        var methodInfo = GetObjType.GetMethod("Dispose");

                        if (methodInfo != null)
                        {
                            TL.LogMessage("Dispose .NET", "  Got Dispose Method Info, Calling Dispose");
                            object result = methodInfo.Invoke(GetLateBoundObject, new object[] { });
                            TL.LogMessage("Dispose .NET", "  Successfully called Dispose method");
                        }
                        else
                        {
                            TL.LogMessage("Dispose .NET", "  No Dispose Method Info so ignoring the call to Dispose");
                        }
                    }
                }
                catch (Exception ex)
                {
                    try
                    {
                        TL.LogMessageCrLf("Dispose", "Exception " + ex.ToString());
                    }
                    catch { }
                } // Ignore any errors here as we are disposing


                //if (TL != null) TL.Dispose(); no longer need to dispose of this as its now handled by AscomDriver
            }
        }