473,398 Members | 2,088 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

Assembly.Load(byte[]) - how does it work? I get TargetInvocationException. Source code included...

My problem:

I load an some assemblies (strong named) from a byte array using
Assembly.Load(byte[]). They load fine. But one one of them is actually
accessed, it's referenced assemblies can't be found on disk and I get a
TargetInvocationExeption.

For example, let's say I have a C# win forms application called Prog.

Prog.exe uses Assembly.Load(byte[]) to load two C# class library assemblies,
ClassLib1 and ClassLib2. Both are strong named. ClassLib1.dll and
ClassLib2.dll are NOT on disk. However, they were created in VS.NET in the
same solution, and ClassLib1 has a reference to ClassLib2 in VS.NET.

The problem is that when my Prog.exe calls a static method on a class in
ClassLib1, I get a TargetInvocationException with the details:
Unhandled Exception: System.Reflection.TargetInvocationException: Exception
has been thrown by the target of an invocation. --->
System.IO.FileNotFoundException: File or assembly name ClassLib2, or one of
its dependencies, was not found.

There are additional details that show that the framework is trying to load
ClassLib2.dll from disk, from the debug (or release) directory where
Prog.exe was started.

In fact, if I do put ClassLib2.dll on disk there, then there is no exception
because it finds it and loads it. Which means it has been loaded twice,
once by me with the Assembly.Load, and once due to the reference from
ClassLib1.

WHY? Why oh why? I've already loaded it!

So how do I make the framework "realize" that it is already loaded? I
thought strong naming would have do the trick, but it didn't make a
difference... it still wants to load it from disk because of the reference
from ClassLib1. Argghhh!

Any help would be GREATLY appreciated...

Thanks!

Greg Patrick

Source code is below if you want to try it out. You just make a VS.NET C#
Win Forms app solution and use Form1 from below. Then make two C# class
library projects ClassLibrary1, and ClassLibrary2. Don't reference either
class library from the main application project. Build. Copy
ClassLibrary1\bin\debug\ClassLibrary1.dll to <application>\bin\debug\C1.dll.
Similarly for ClassLibrary2.dll - copy to C2.dll.

----------------------------------------------------------------------------
-------------------------------

ClassLibrary2

using System;
namespace ClassLibrary2
{
public class Class2
{
public Class2()
{
}
}
}

ClassLibrary1 (Note, in VS.NET, has a reference to ClassLibrary2):

using System;
using System.Windows.Forms;
using ClassLibrary2;
namespace ClassLibrary1
{
public class Class1
{
public static Class2 class2 = new Class2();

public Class1()
{
}

public static void Hello()
{
MessageBox.Show("Hello!");
}
}
}

Prog.exe's Form1:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Reflection;
namespace WinApp
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;

private Assembly LoadAss(string filename)
{
FileStream fin = new FileStream("c1.dll", FileMode.Open,
FileAccess.Read);
byte[] bin = new byte[16384];
long rdlen = 0;
long total= fin.Length;
int len;
MemoryStream memStream = new MemoryStream((int)total);
rdlen = 0;
while(rdlen < total)
{
len = fin.Read(bin, 0, 16384);
memStream.Write(bin, 0, len);
rdlen = rdlen + len;
}
// done with input file
fin.Close();
return Assembly.Load(memStream.ToArray());
}

public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
Assembly c1 = this.LoadAss("c1.dll");
this.LoadAss("c2.dll");
Type t = c1.GetType("ClassLibrary1.Class1");
MethodInfo m = t.GetMethod("Hello");
m.Invoke(null, new object[]{});
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Size = new System.Drawing.Size(300,300);
this.Text = "Form1";
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
}
}
Nov 16 '05 #1
1 15879
You have to manage AssemblyResolve and make sure to return your dynamic
assembly whenever a request for your second strongly typed assembly is made.
What I would recommend is using Assembly.Load(byte[]), and then inserting
the Assembly references into a Hashtable that you can index later.

I have some information on this on my blog. Note, that because your assemblies
are strong named, you might not want to use basic name resolving and instead use
a more complete resolving based on the full name. That is completely up to your
discretion.

http://weblogs.asp.net/justin_rogers...07/149964.aspx

--
Justin Rogers
DigiTec Web Consultants, LLC.
Blog: http://weblogs.asp.net/justin_rogers

"Greg Patrick" <pr*****@private.com> wrote in message
news:WlJyc.1204$0A.9411@localhost...
My problem:

I load an some assemblies (strong named) from a byte array using
Assembly.Load(byte[]). They load fine. But one one of them is actually
accessed, it's referenced assemblies can't be found on disk and I get a
TargetInvocationExeption.

For example, let's say I have a C# win forms application called Prog.

Prog.exe uses Assembly.Load(byte[]) to load two C# class library assemblies,
ClassLib1 and ClassLib2. Both are strong named. ClassLib1.dll and
ClassLib2.dll are NOT on disk. However, they were created in VS.NET in the
same solution, and ClassLib1 has a reference to ClassLib2 in VS.NET.

The problem is that when my Prog.exe calls a static method on a class in
ClassLib1, I get a TargetInvocationException with the details:
Unhandled Exception: System.Reflection.TargetInvocationException: Exception
has been thrown by the target of an invocation. --->
System.IO.FileNotFoundException: File or assembly name ClassLib2, or one of
its dependencies, was not found.

There are additional details that show that the framework is trying to load
ClassLib2.dll from disk, from the debug (or release) directory where
Prog.exe was started.

In fact, if I do put ClassLib2.dll on disk there, then there is no exception
because it finds it and loads it. Which means it has been loaded twice,
once by me with the Assembly.Load, and once due to the reference from
ClassLib1.

WHY? Why oh why? I've already loaded it!

So how do I make the framework "realize" that it is already loaded? I
thought strong naming would have do the trick, but it didn't make a
difference... it still wants to load it from disk because of the reference
from ClassLib1. Argghhh!

Any help would be GREATLY appreciated...

Thanks!

Greg Patrick

Source code is below if you want to try it out. You just make a VS.NET C#
Win Forms app solution and use Form1 from below. Then make two C# class
library projects ClassLibrary1, and ClassLibrary2. Don't reference either
class library from the main application project. Build. Copy
ClassLibrary1\bin\debug\ClassLibrary1.dll to <application>\bin\debug\C1.dll.
Similarly for ClassLibrary2.dll - copy to C2.dll.

----------------------------------------------------------------------------
-------------------------------

ClassLibrary2

using System;
namespace ClassLibrary2
{
public class Class2
{
public Class2()
{
}
}
}

ClassLibrary1 (Note, in VS.NET, has a reference to ClassLibrary2):

using System;
using System.Windows.Forms;
using ClassLibrary2;
namespace ClassLibrary1
{
public class Class1
{
public static Class2 class2 = new Class2();

public Class1()
{
}

public static void Hello()
{
MessageBox.Show("Hello!");
}
}
}

Prog.exe's Form1:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Reflection;
namespace WinApp
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;

private Assembly LoadAss(string filename)
{
FileStream fin = new FileStream("c1.dll", FileMode.Open,
FileAccess.Read);
byte[] bin = new byte[16384];
long rdlen = 0;
long total= fin.Length;
int len;
MemoryStream memStream = new MemoryStream((int)total);
rdlen = 0;
while(rdlen < total)
{
len = fin.Read(bin, 0, 16384);
memStream.Write(bin, 0, len);
rdlen = rdlen + len;
}
// done with input file
fin.Close();
return Assembly.Load(memStream.ToArray());
}

public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
Assembly c1 = this.LoadAss("c1.dll");
this.LoadAss("c2.dll");
Type t = c1.GetType("ClassLibrary1.Class1");
MethodInfo m = t.GetMethod("Hello");
m.Invoke(null, new object[]{});
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Size = new System.Drawing.Size(300,300);
this.Text = "Form1";
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
}
}

Nov 16 '05 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Mitchell Vincent | last post by:
I'm sure this has been discussed here plenty of times before (feel free to point me to the thread!) but I want to learn as much as possible about the single most talked about issue with .NET...
8
by: Michael Dekson | last post by:
Hello, Can I exe file made in Microsoft Visual C++ decompile into source code. If it is possibly please tell me how. Thanks
19
by: Martin Oddman | last post by:
Hi, I have a compiling problem. Please take a look at the code below. I have an application that is built upon three tiers: one data tier (Foo.DataManager), one business tier (Foo.Kernel) and...
1
by: mathlec | last post by:
I'm struggling with an odd problem and I want to validate something. What is the right way to load an assembly from bytes? Is this code correct? : .... Private Function loadBytes(filename...
3
by: Peter | last post by:
I have a VB.net exe ----> I want to load in more VB.net Source code into my VB app ---> and then compile a new EXE file from within my original program. Has anyone done this? I'm looking for...
5
by: iamcs1983 | last post by:
Can I load a assembly from memory by Assembly.Load(string) ?
6
by: Steve | last post by:
I'm playing with late binding and trying a very simple test to load an assembly In my "Host" application I have this code: <code> string modulePath =...
0
by: Boni | last post by:
Dear all, the Assembly.load(ByteArray() ) function works very slow for me (sometimes about 10 sec for 1 MB assembly). Is there any chance for speed up? --- Overloads Public Shared Function...
1
by: =?Utf-8?B?QU1lcmNlcg==?= | last post by:
I have a vb.net program that needs to display a few fragments of its source code, typically one to five lines for each fragment, and each line contains one assignment statement. I need to do this...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.