I've got some code that is using reflection to install .NET event handlers on MSHTML objects in an Internet Explorer BHO, and it appears to be working fine. I'm running into trouble, however, when I try to remove the event handlers.
This is what the code for event handler installation and removal looks like:
public class HandlerExample {
private static void Handler(IHTMLEventObj e) { ... }
private static Delegate handlerDelegate;
public static void InstallHandler(IHTMLElement target, string eventName)
{
// FindInterface() finds the correct event interface for the particular subclass of
// IHTMLElement that target really is
Type eventInterface = FindInterface(target);
EventInfo eInfo = eventInterface.GetEvent(eventName);
Type tHandler = eInfo.EventHandlerType;
handlerDelegate = Delegate.CreateDelegate(tHandler, typeof(HandlerExample), "Handler");
eInfo.AddEventHandler(target, handlerDelegate);
}
public static void RemoveHandler(IHTMLElement target, string eventName)
{
Type eventInterface = FindInterface(target);
EventInfo eInfo = eventInterface.GetEvent(eventName);
eInfo.RemoveEventHandler(target, handlerDelegate); // THIS LINE CRASHES
}
}
The call to InstallEventHandler works fine, and Handler then gets called when the event is triggered in the browser. When I call RemoveEventHandler with the same arguments as the InstallEventHandler call, the last line throws a TargetInvocationException, with an inner exception of NullReferenceException. I can't figure out what I'm doing wrong here, and the stack trace is not much help.
EDIT: I've stepped through the code in the debugger, and none of the object variables I directly reference are null.
I've also tried calling both AddEventHandler and RemoveEventHandler in the InstallHandler method, and that works correctly.
Stack trace follows:
System.Reflection.TargetInvocationException occurred
Message="Exception has been thrown by the target of an invocation."
Source="mscorlib"
StackTrace:
at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.EventInfo.RemoveEventHandler(Object target, Delegate handler)
at RemoveHandler(IHTMLElement target, String eventName)
InnerException: System.NullReferenceException
Message="Object reference not set to an instance of an object."
Source="Microsoft.mshtml"
StackTrace:
at mshtml.HTMLTextContainerEvents2_EventProvider.remove_onclick(HTMLTextContainerEvents2_onclickEventHandler )
at mshtml.HTMLTextAreaElementClass.HTMLTextContainerEvents2_Event_remove_onclick(HTMLTextContainerEvents2_onclickEventHandler )
InnerException:
What could be causing this, and how can I fix it?
Well it looks like your handlerDelegate is null when you are calling the RemoveHandler.
I am not sure why this would happen, but have you tried instantiating the handlerDelegate right before calling RemoveEventHandler?
Related
I received the following error message when running SSIS package. The Script Task is using Microsoft Visual C# 2008. Can you please help me to fix the problem?
Thank you very much! I also attach error message:
Error: 2015-12-22 02:58:08.28
Code: 0x00000001
Source: Script Task
Description: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: Showing a modal dialog box or form when the application is not running in UserInteractive mode is not a valid operation. Specify the ServiceNotification or DefaultDesktopOnly style to display a notification from a service application.
at System.Windows.Forms.MessageBox.ShowCore(IWin32Window owner, String text, String caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, MessageBoxOptions options, Boolean showHelp)
at System.Windows.Forms.MessageBox.Show(String text)
at ST_d27b216cd7d64713b54c81f6ac28d805.csproj.ScriptMain.Main()
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
at System.Type.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, CultureInfo culture)
at Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTATaskScriptingEngine.ExecuteScript()
End Error
DTExec: The package execution returned DTSER_FAILURE (1).
C# code:
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
namespace ST_d27b216cd7d64713b54c81f6ac28d805.csproj
{
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
#region VSTA generated code
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
public void Main()
{
// TODO: Add your code here
System.IO.FileInfo fi;
String FilePath = null;
DateTime ModifiedTime = (DateTime)Dts.Variables["File_Modified"].Value;
DateTime LoadDate = (DateTime)Dts.Variables["File_Last_Load_Date"].Value;
Dts.Variables["isModified"].Value = false;
FilePath = Dts.Variables["SourceFolder"].Value.ToString();
ModifiedTime = System.IO.File.GetLastWriteTime(FilePath);
Dts.Variables["File_Modified"].Value = ModifiedTime;
// fi.LastWriteTime;
int result = DateTime.Compare(ModifiedTime, LoadDate);
if (result > 0)
{
MessageBox.Show("File Modified after last load in staging");
Dts.Variables["isModified"].Value = true;
}
else
{
MessageBox.Show("file is not modified since last load");
Dts.Variables["isModified"].Value = false;
}
Dts.TaskResult = (int)ScriptResults.Success;
}
}
}
The error message extracted from your stack trace is:
Showing a modal dialog box or form when the application is not running in UserInteractive mode is not a valid operation. Specify the ServiceNotification or DefaultDesktopOnly style to display a notification from a service application.
You have to remember that although when you are debugging your SSIS package you have a nice UI (BIDS or SQL Server Tools shells depending on your environment) but really it is not designed to be have a UI. What would you expect to happen when this package is deployed to a server and called by a SQL Job? i.e. Where would the message box show? Who would click "OK" to allow the thread to resume?
You probably want to just fire an information event if you are looking to post feedback, something like:
bool fireAgain = false;
Dts.Events.FireInformation(0, "Script Task", "File Modified after last load in staging", String.Empty, 0, ref fireAgain);
The error is raised because your script task is trying to display a message box and showing a modal dialog box or form when the application is not running in UserInteractive mode is not a valid operation. Therefore if you want to output a message, you could use Dts.Log instead, see the MSDN documentation for further details.
I am trying to replicate a functionality with reflection but end up getting
createFormatMethod.Invoke(typDbFormatClass, null)' threw an exception of type 'System.Reflection.TargetInvocationException' object {System.Reflection.TargetInvocationException}
Inner Exception Shows Object reference not set to an instance of an object.
System.NullReferenceException
InnerException null
Stacktrace
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at AB.INIT.stringToValue(String valueInUnits, String dimension, String sourceUnit, String destinationUnit)
I am trying to access a static method of abstract class here. Below is the direct reference code that works perfectly .
Binit.Core.Database.DbFormat format;
format = Binit.Core.Database.DbFormat.Create();
format.Dimension = DbDoubleDimension.GetDimension(
(DbDimension)Enum.Parse(typeof(DbDimension), dimension));
format.Units = DbDoubleUnits.GetUnits(
(DbUnits)Enum.Parse(typeof(DbUnits), destinationUnit));
Reflection Code which fails and shows targetinvocationexception
Assembly CoreDatabaseAssembly =
Assembly.LoadFrom(Path.Combine(APath, #"Binit.Core.Database.dll"));
Type typDbFormatClass = CoreDatabaseAssembly.GetType("Binit.Core.Database.DbFormat");
MethodInfo createFormatMethod = typDbFormatClass.GetMethod("Create",
BindingFlags.Static | BindingFlags.Public, null, new Type[] { }, null);
object objDbFormat = createFormatMethod.Invoke(typDbFormatClass, null);
Can someone help me understand what i could be doing wrong with invoke method
I'm writing SSIS that scans a SQL table, create an object from each record values and need to move it next to other SSIS flow elements.
I created object type variable (MyObject) and script task.
In my script task I wrote the next code:
RequestObject reqObj = new RequestObject();
reqObj.building = Dts.Variables["reqObj_Building"].Value.ToString();
reqObj.ID = Convert.ToInt32(Dts.Variables["reqObj_DeviceID"].Value);
//...
Now I tried to write the next code in order to assin reqObj into myObject.
Dts.Variables["myObject"].Value = new RequestObject();
Dts.Variables["myObject"].Value = reqObj;
but those lines throws the next run time exception :
Error: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> Microsoft.SqlServer.Dts.Runtime.DtsRuntimeException: The element cannot be found in a collection. This error happens when you try to retrieve an element from a collection on a container during execution of the package and the element is not there.
---> System.Runtime.InteropServices.COMException (0xC0010009): The element cannot be found in a collection. This error happens when you try to retrieve an element from a collection on a container during execution of the package and the element is not there.
at Microsoft.SqlServer.Dts.Runtime.Wrapper.IDTSVariables100.get_Item(Object Index)
at Microsoft.SqlServer.Dts.Runtime.Variables.get_Item(Object index)
--- End of inner exception stack trace ---
at Microsoft.SqlServer.Dts.Runtime.Variables.get_Item(Object index)
at ST_a3e0b574a8964ffb8af6f9fee31d5afd.csproj.ScriptMain.Main()
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
at System.Type.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, CultureInfo culture)
at Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTATaskScriptingEngine.ExecuteScript()
How can I assign custom object into SSIS Object type variable ?
It it possible?
Thanks
I don't have enough reputation to comment so I'm adding an answer instead. I did the below steps to try and replicate your problem:
Created a new script task
Created a new class in the namespace of that script
Created a variable of type Object and added to script task as Read/Write variable
Initialised the new class and assigned that value to the Object variable.
Below is my code which ran successfully. Can you please explain if there is any thing I am missing/understanding wrong?
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
namespace ST_8eab6a8fbc79431c8c9eb80339c09d1d.csproj
{
public class myclass
{
int a, b;
public myclass()
{
a = 0;
b = 0;
}
}
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
#region VSTA generated code
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
public void Main()
{
Dts.TaskResult = (int)ScriptResults.Success;
myclass m = new myclass();
Dts.Variables["myObject"].Value = m;
}
}
}
I have an application test framework developed in C# which stores the result in an Excel file after each step. When executed inside the solution everything works fine. But when I am integrating the solution with Fitnesse and calling the method, an error is thrown. I have added the stack trace from Fitness below.
The code segment is here:
public class ExcelReports : IReporter
{
private Excel.Application xlReport;
public ExcelReports()
{
xlReport = new Excel.Application();
Excel.Workbook xlWorkbook = xlReport.Workbooks.Add();
***xlWorkbook.SaveAs(ExecutionContext.RESULTFILE);***
}
}
The error is reported at xlWorkbook.SaveAs(ExecutionContext.RESULTFILE)
I am using the fit and fitsharp dlls for the .NET 4.0 release.
System.Reflection.TargetInvocationException: Exception has been thrown by the
target of an invocation. ---> System.Reflection.TargetInvocationException:
Exception has been thrown by the target of an invocation. --->
System.Runtime.InteropServices.COMException: Microsoft Excel cannot access the file
'C:\0452CB00'. There are several possible reasons:
• The file name or path does not exist.
• The file is being used by another program.
• The workbook you are trying to save has the same name as a currently open
workbook.
at Microsoft.Office.Interop.Excel._Workbook.SaveAs(Object Filename, Object
FileFormat, Object Password, Object WriteResPassword, Object ReadOnlyRecommended,
Object CreateBackup, XlSaveAsAccessMode AccessMode, Object ConflictResolution,
Object AddToMru, Object TextCodepage, Object TextVisualLayout, Object Local)
at EF.UIAutomation.Commons.ExcelReports..ctor() in
C:\EF.Automation\EF.UIAutomation.PageLibrary\Libraries\EF.UIAutomation.Commons.Reports.cs:l ine 25
at EF.UIAutomation.Launcher.Program.Test() in
C:\EF.Automation\EF.Automation\Program.cs:line 26
--- End of inner exception stack trace ---
at fitSharp.Machine.Model.TypedValue.ThrowExceptionIfNotValid()
at fitSharp.Fit.Operators.CompareDefault.Compare(TypedValue actualValue, Tree`1
expected)
at fitSharp.Machine.Engine.ProcessorBase`2.<>c__DisplayClass3.
<>c__DisplayClass5.b__2(CompareOperator`1 o)
at fitSharp.Machine.Engine.Operators`2.Do[O](CanDoOperation`1 canDoOperation,
DoOperation`1 doOperation)
at fitSharp.Machine.Engine.ProcessorBase`2.
<>c__DisplayClass3.b__0(OperationLogging logging)
at fitSharp.Machine.Engine.ProcessorBase`2.DoLoggedOperation[R](String
startMessage, Func`2 operation)
at fitSharp.Machine.Engine.ProcessorBase`2.Compare(TypedValue instance, Tree`1
parameters)
at fitSharp.Fit.Operators.CheckDefault.Check(CellOperationValue actualValue,
Tree`1 expectedCell)
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments,
Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[]
parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr,
Binder binder, Object[] parameters, CultureInfo culture)
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder
binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers,
CultureInfo culture, String[] namedParams)
at fitSharp.Machine.Engine.MethodMember.TryInvoke(Object[] parameters)
at fitSharp.Machine.Engine.ReflectionMember.Invoke(Object[] parameters)
at fitSharp.Machine.Engine.ProcessorBase`2.Operate[O](Object[] parameters)
at fitSharp.Fit.Engine.CellProcessorExtension.Check(CellProcessor processor,
Object systemUnderTest, Tree`1 memberName, Tree`1 parameters, Tree`1 expectedCell)
at fitSharp.Fit.Service.CheckBinding.Do(Tree`1 cell)
at fitSharp.Fit.Service.Binding.Do(Tree`1 cell)
at fit.ColumnFixture.DoCell(Parse cell, Int32 column)
I am trying to use SSIS to open an Excel file and refresh the data before importing the data into SQL Server. My dtsx package is failing on the line of code that tries to open the Excel file.
The code is straightforward and taken from here.
This is the code I am using:
public void Main()
{
// TODO: Add your code here
Dts.TaskResult = (int)ScriptResults.Success;
Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook wb;
wb = excel.Workbooks.Open(#"C:\Test.xlsx",0, false, null, null, null, true, null, null, null, null, null, null, null, null);
//wb.RefreshAll();
//wb.Save();
//wb.Close(null, null, null);
excel.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
}
The error message is as follows:
Error: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Runtime.InteropServices.COMException (0x800A03EC): Exception from HRESULT: 0x800A03EC
at Microsoft.Office.Interop.Excel.Workbooks.Open(String Filename, Object UpdateLinks, Object ReadOnly, Object Format, Object Password, Object WriteResPassword, Object IgnoreReadOnlyRecommended, Object Origin, Object Delimiter, Object Editable, Object Notify, Object Converter, Object AddToMru, Object Local, Object CorruptLoad)
at ST_2177878595ee4288864728b04a894c16.csproj.ScriptMain.Main()
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
at Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTATaskScriptingEngine.ExecuteScript()
I am currently working on my test machine with the following configuration:
Visual Studio 2008 BIDS
Office 2010
Office 2010 PIAs
Does anyone have any suggestions as to how to get this working?
Use Type.Missing in place of null. And also ref before each variable. See http://msdn.microsoft.com/en-us/library/system.type.missing(v=VS.90).aspx