/// <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); } }
/// <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 } }