Microsoft KB Archive/828991

= PRB: &quot;System.Reflection.TargetInvocationException&quot; Error Message When You Call the MethodInfo.Invoke Method =

Article ID: 828991

Article Last Modified on 4/19/2007

-

APPLIES TO


 * Microsoft .NET Framework 1.1
 * Microsoft .NET Framework 1.0
 * Microsoft Common Language Runtime (included with the .NET Framework 1.1)
 * Microsoft Common Language Runtime (included with the .NET Framework) 1.0
 * Microsoft Visual Studio .NET 2003 Enterprise Architect
 * Microsoft Visual Studio .NET 2003 Enterprise Developer
 * Microsoft Visual Studio .NET 2003 Professional Edition
 * Microsoft Visual Studio .NET 2003 Academic Edition
 * Microsoft Visual Studio .NET 2002 Enterprise Architect
 * Microsoft Visual Studio .NET 2002 Enterprise Developer
 * Microsoft Visual Studio .NET 2002 Professional Edition
 * Microsoft Visual Studio .NET 2002 Academic Edition
 * Microsoft Visual C# .NET 2003 Standard Edition
 * Microsoft Visual C# .NET 2002 Standard Edition
 * Microsoft Visual Basic .NET 2003 Standard Edition
 * Microsoft Visual Basic .NET 2002 Standard Edition

-





SYMPTOMS
When you call the MethodInfo.Invoke method, you may receive the following error message:

An unhandled exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll

Additional information: Exception has been thrown by the target of an invocation.

You may also receive an additional error message that is similar to the following error message:

Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.FileLoadException: 'ClassLibrary1' is not a valid file.

File name: &quot;ClassLibrary1&quot;

at ClassLibrary2.Class1.GetString



CAUSE
You receive the System.Reflection.TargetInvocationException error because the common language runtime calls the MethodInfo.Invoke method by using reflection.

When you load an assembly by using the Assembly.LoadFrom method, the common language runtime places the loaded assembly in the LoadFrom context of your application. Any probes for the dependencies of the assembly first probe the current application directory. If this probe fails, the common language runtime then probes the LoadFrom context of your application.

You may load an assembly that has a simply-named dependency that has the same file name as a file in the current application directory. When you try to invoke a method in the loaded assembly by using the MethodInfo.Invoke method, and the invoked method uses the dependency, the common language runtime first probes the current directory path. When the common language runtime finds a file that has the same file name as the dependency, the probe stops. However, if this file does not have the same assembly identity as the dependency, the assembly bind fails, and the common language runtime generates a System.IO.FileLoadException error that is passed to the System.Reflection.TargetInvocationException error. Therefore, you may notice the behavior that is mentioned in the &quot;Symptoms&quot; section.



WORKAROUND
To work around this problem, either rename the file that exists in the current application directory so that this file has a different file name from the dependency of the loaded assembly, or install the dependency in the Global Assembly Cache (GAC) that has precedence over the current application directory during probing.

Rename the File That Exists in the Current Application Directory

Note The following procedure is based on the sample that is mentioned in the &quot;More Information&quot; section. Therefore, the code and the file names in this procedure may differ from your code and from your file names.
 * 1) Locate the ClassLibrary1.dll text file that you created in step 16 of the &quot;More Information&quot; section.
 * 2) Change the name of the ClassLibrary1.dll file to any name other than ClassLibrary1.dll.

For example, you may rename this file to Renamed_ClassLibrary1.dll.
 * 1) Run your application from the command prompt.

You notice the following output:

ClassLibrary1.GetString result: ClassLibrary1.Class1

Install the Dependency in the GAC

Note The following procedure is based on the sample that is mentioned the &quot;More Information&quot; section. Therefore, the code and the file names in this procedure may differ from your code and from your file names.  From a Microsoft Visual Studio .NET command prompt, change the directory path of the location of the ClassLibrary1.dll assembly that you built in step 3 of the &quot;More Information&quot; section. At the Visual Studio .NET command prompt, run the following command to create a strong name:

sn -k C:\Key.snk   If you are using Microsoft Visual C# .NET, locate the following code in the AssemblyInfo.cs file of the ClassLibrary1 project: [assembly: AssemblyKeyFile(&quot;&quot;)] If you are using Microsoft Visual Basic .NET, locate the following code in the AssemblyInfo.vb file of the ClassLibrary1 project:    If you are using Visual C# .NET, replace the code that you located in the previous step with the following code: [assembly: AssemblyKeyFile(&quot;C:\\Key.snk&quot;)] If you are using Visual Basic .NET, add the following code after the code that you located in the previous step:   Build the ClassLibrary1 project to re-create the ClassLibrary1.dll assembly.</li> Run the following command at the Visual Studio .NET command prompt to install the ClassLibrary1.dll assembly in the GAC:

gacutil -if ClassLibrary1.dll </li> In the ClassLibrary2 project, delete the existing project reference to the ClassLibrary1.dll assembly.</li> In the ClassLibrary2 project, add a project reference to the ClassLibrary1.dll assembly that you rebuilt in step 5.</li> Build the ClassLibrary2 project to re-create the ClassLibrary2.dll assembly.</li> From the Visual Studio .NET command prompt, run your application.

You notice the following output:

ClassLibrary1.GetString result: ClassLibrary1.Class1</li></ol>

<div class="status_section">

STATUS
This behavior is by design.

<div class="moreinformation_section">

Steps to Reproduce the Behavior
<ol> Start Visual Studio .NET.</li> Use either Visual C# .NET or Visual Basic .NET to create a Class Library project.

By default, the Class1 class is created.</li> Build this project to create the ClassLibrary1.dll assembly.</li> Use either Visual C# .NET or Visual Basic .NET to add a new Class Library project to your solution.

By default, the Class1 class is created.</li> In the ClassLibrary2 project, add a project reference to the ClassLibrary1.dll assembly that you built in step 3.</li>  If you are using Visual C# .NET, locate the following code in the Class1.cs file of the ClassLibrary2 project: public Class1 {  //   // TODO: Add constructor logic here // } If you are using Visual Basic .NET, locate the following code in the Class1.vb file of the ClassLibrary2 project: Public Class Class1 </li>  If you are using Visual C# .NET, add the following code after the code that you located in the previous step: public string GetString {  return new ClassLibrary1.Class1.ToString; } If you are using Visual Basic .NET, add the following code after the code that you located in the previous step: Public Function GetString As String Return New ClassLibrary1.Class1.ToString End Function </li> Build the ClassLibrary2 project to create the ClassLibrary2.dll assembly.</li> Use either Visual C# .NET or Visual Basic .NET to add a new Console Application project to your solution.

By default, the Class1 class is created in Visual C# .NET, and the Module1 module is created in Visual Basic .NET.</li>  If you are using Visual C# .NET, locate the following code in the Class1.cs file of the ConsoleApplication1 project: using System; If you are using Visual Basic .NET, locate the following code in the Module1.vb file of the ConsoleApplication1 project: Module Module1 </li>  If you are using Visual C# .NET, add the following code after the code that you located in the previous step: using System.Reflection; If you are using Visual Basic .NET, add the following code before the code that you located in the previous step: Imports System.Reflection </li> <li> If you are using Visual C# .NET, add the following code to the Main method of the Class1 class: Assembly myAssembly; myAssembly = Assembly.LoadFrom(@&quot;C:\828991\ClassLibrary2\bin\Debug\ClassLibrary2.dll&quot;); Type myType = myAssembly.GetTypes[0]; MethodInfo myMethod = myType.GetMethod(&quot;GetString&quot;); object obj = myAssembly.CreateInstance(myType.FullName); Console.WriteLine(&quot;ClassLibrary1.GetString result: {0}&quot;, myMethod.Invoke(obj, null)); Note In the Assembly.LoadFrom method, use an appropriate path that corresponds to the location of the ClassLibrary2.dll assembly on your computer.

If you are using Visual Basic .NET, add the following code to the Main method of the Module1 module: Dim MyAssembly As [Assembly] MyAssembly = [Assembly].LoadFrom(&quot;C:\828991\ClassLibrary2\bin\ClassLibrary2.dll&quot;) Dim MyType As Type = MyAssembly.GetTypes(0) Dim MyMethod As MethodInfo = MyType.GetMethod(&quot;GetString&quot;) Dim Obj As Object = MyAssembly.CreateInstance(myType.FullName) Console.WriteLine(&quot;ClassLibrary1.GetString result: {0}&quot;, MyMethod.Invoke(obj, Nothing)) Note In the Assembly.LoadFrom method, use an appropriate path that corresponds to the location of the ClassLibrary2.dll assembly on your computer. </li> <li>Build the ConsoleApplication1 project to create the ConsoleApplication1.exe file.</li> <li>Start Notepad.</li> <li>Type the following text in Notepad:

This is not an assembly. </li> <li>Save the Notepad document as ClassLibrary1.dll in the same location as the ConsoleApplication1.exe file that you built in step 13.</li> <li>From the command prompt, run the ConsoleApplication1.exe file.

You notice the behavior that is mentioned in the &quot;Symptoms&quot; section.</li></ol>

<div class="references_section">