Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / .NET SDK / July 2007

Tip: Looking for answers? Try searching our database.

LoadAssembly, GetType - can't find reference

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
David Thielen - 17 Jul 2007 18:26 GMT
Hi;

I am trying to create an object from a dynamically loaded assembly. This
dynamically loaded assembly has a reference to a dll that the loading program
also has.

Trying to debug it I call:
Assembly a.s = Assembly.LoadFile(parts[0]);
object obj = a.s.GetExportedTypes();

And the call to GetExportedTypes() throws an exception saying it cannot find
the referenced dll WindwardReports.dll - which is also referenced by the code
making this call.

This is in a Word AddIn.

Any ideas?

Signature

thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Cubicle Wars - http://www.windwardreports.com/film.htm

Walter Wang [MSFT] - 18 Jul 2007 02:25 GMT
Hi Dave,

I suggest first to use fusion log viewer
(http://blogs.msdn.com/junfeng/archive/2004/02/14/72912.aspx) to get
detailed error.

I cannot seem to reproduce the issue using a console application and two
class libraries. Can you tell me more about the configuration such as are
the assemblies strong named, where are they located? Of course it would be
great if you could send me a reproducible project to test.

Regards,
Walter Wang (wawang@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
David Thielen - 18 Jul 2007 17:34 GMT
Hi;

Found the problem. The log shows:
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using machine configuration file from
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom,
partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Program Files/Microsoft
Office/OFFICE12/AutoSizeBean.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/Microsoft
Office/OFFICE12/AutoSizeBean/AutoSizeBean.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/Microsoft
Office/OFFICE12/AutoSizeBean.EXE.
LOG: Attempting download of new URL file:///C:/Program Files/Microsoft
Office/OFFICE12/AutoSizeBean/AutoSizeBean.EXE.
LOG: All probing URLs attempted and failed.

However, I load the assembly using:
string filename = Path.GetFullPath(parts[0]);
Assembly a.s = Assembly.LoadFile(filename);
object obj = a.s.GetTypes();

where filename points to the dll file - which is in a different directory.
And LoadFile() returns an object. So why is it not looking in the directory
where the file is?

Signature

thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Cubicle Wars - http://www.windwardreports.com/film.htm

> Hi Dave,
>
[quoted text clipped - 17 lines]
>
> This posting is provided "AS IS" with no warranties, and confers no rights.
Walter Wang [MSFT] - 20 Jul 2007 11:05 GMT
Hi Dave,

Sorry for delayed reply, I was not in office yesterday.

Is it a full path or just the file name?

The log seems normal, that's how fusion loads a private assembly (not in
GAC), it will try with the assembly name and a subdirectory with the same
name, also extension will be tried with DLL and EXE.

Can you tell me more about your assembly's naming and location? Do you have
duplicated copies?

Regards,
Walter Wang (wawang@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
David Thielen - 20 Jul 2007 16:58 GMT
It gives the full filename. I even call Patg.GetFullName() on it to make sure
it is the full name.

Signature

thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Cubicle Wars - http://www.windwardreports.com/film.htm

> Hi Dave,
>
[quoted text clipped - 19 lines]
>
> This posting is provided "AS IS" with no warranties, and confers no rights.
Walter Wang [MSFT] - 23 Jul 2007 06:45 GMT
Hi Dave,

What I meant is that what's the correct complete full path? Fusion tried
with C:/Program Files/Microsoft
Office/OFFICE12/AutoSizeBean.DLL, but this is apparently not correct, right?

Could you please tell me more about the scenario to help me reproduce the
issue on my side?

Regards,
Walter Wang (wawang@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
David Thielen - 23 Jul 2007 15:50 GMT
Hi;

I am calling:
Assembly a.s =
Assembly.LoadFile("c:\\src\\kahuna\\AutoTag\\AutoTagCore\\bin\\debug\\AutoSizeBean.dll");
object obj = a.s.GetExportedTypes();

So it is getting the full path. But it never looks there.

Signature

thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Cubicle Wars - http://www.windwardreports.com/film.htm

> Hi Dave,
>
[quoted text clipped - 15 lines]
>
> This posting is provided "AS IS" with no warranties, and confers no rights.
Walter Wang [MSFT] - 24 Jul 2007 13:30 GMT
Hi Dave,

This is my understanding of your configuration so far:

<your main app dir>\
 <your addin>.dll
 WindWardReports.dll

c:\src\kahuna\AutoTag\AutoTagCore\bin\debug\
 AutoSizeBean.dll
 WindWardReports.dll

And from <your addin>.dll, you're trying to call
LoadFile("c:\src\kahuna\AutoTag\AutoTagCore\bin\debug\AutoSizeBean.dll"),
the loading is successfully, but if you call the returned
Assembly.GetExportedTypes(), .NET reports error that it cannot find
"WindWardReports.dll".

I created a test solution locally which includes three projects:

* ConsoleApplication1, references ClassLibrary1
* ClassLibrary1
* ClassLibrary2, references ClassLibrary1

In ConsoleApplication1, I used an absolute path to call
LoadFile("...ClassLibrary2.dll"), this works correctly and the
GetExportedTypes() also runs correctly. In this case, the fusion log also
shows it tries to load ClassLibrary2 from the directory where
ConsoleApplication1.exe resides, this seems can be ignored since the
ClassLibrary2.dll is loaded successfully.

Basically I'm saying that I cannot reproduce the issue you mentioned, can
you create a reproducible project on your side and send it to me? Thanks.

Regards,
Walter Wang (wawang@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
David Thielen - 25 Jul 2007 06:52 GMT
Hi;

Not exactly. It is a Word AddIn in C# (IExtensibility, not VSTO) and that
dll tries to load the other dll. I have a small sample but I have to go home
now so I will not be able to get it bundled up and emailed to you until
tomorrow.

But the problem appears to be trying to do this in a Word AddIn. Word may be
causing the problem.

Signature

thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Cubicle Wars - http://www.windwardreports.com/film.htm

> Hi Dave,
>
[quoted text clipped - 40 lines]
>
> This posting is provided "AS IS" with no warranties, and confers no rights.
David Thielen - 26 Jul 2007 05:48 GMT
Hi;

I wrote a small test program - and it works fine. Obviously there is a
difference but I have no idea what.

Any idea what would cause it not to look in the file an assembly is created
from for the types in that assembly? It's the Assembly.GetTypes() that is
failing after it returns a good object on Assembly.LoadFile().

One thing I did not duplicate in the sample program - I am calling this in
an event handler. Is it possible the event handler is in a Word thread rather
than that of my AddIn? And if so, how do I get it back to my AddIn's thread?
It is all the code I am calling in the event handler the Assembly.LoadFile()
and Assembly.GetTypes().

Signature

thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Cubicle Wars - http://www.windwardreports.com/film.htm

> Hi Dave,
>
[quoted text clipped - 40 lines]
>
> This posting is provided "AS IS" with no warranties, and confers no rights.
Walter Wang [MSFT] - 26 Jul 2007 11:17 GMT
Hi Dave,

I've downloaded the test project and found it's throwing the exception when
I call a.s.GetTypes() as your described. However, if you look into the
exception, .NET is trying to load WindwardReports.dll from GAC instead of
the private copy. After I intalled the WindwardReports.dll into GAC, the
type loads successfully. (Your C# test project isn't referening the
assembly, that's why it succeeds)

To see if this is the issue of Word add-in, I created a local word add-in
for test but it seems a simple strong named assembly doesn't reproduce the
issue. I think this might be related how WindwardReports.dll is built,
could you please depict more?

Regards,
Walter Wang (wawang@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
David Thielen - 26 Jul 2007 15:28 GMT
For my real case (not the test case), the program loading the dll has already
made a call to WindwardReports.dll so WindwardReports.dll is already loaded -
why is it not finding it?

Signature

thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Cubicle Wars - http://www.windwardreports.com/film.htm

> Hi Dave,
>
[quoted text clipped - 20 lines]
>
> This posting is provided "AS IS" with no warranties, and confers no rights.
Walter Wang [MSFT] - 30 Jul 2007 06:48 GMT
Hi Dave,

I've done some further research and I think I've found the root cause now.

Per the documentation of LoadFile:

<quote>
Use the LoadFile method to load and examine assemblies that have the same
identity, but are located in different paths. LoadFile does not load files
into the LoadFrom context, and does not resolve dependencies using the load
path, as the LoadFrom method does. LoadFile is useful in this limited
scenario because LoadFrom cannot be used to load assemblies that have the
same identities but different paths; it will load only the first such
assembly.
</quote>

Two points here:

1) LoadFile does not resolve dependencies using the load path.

Therefore, if we call LoadFile("<path>\ClassLibrary2.dll") which references
ClassLibrary1.dll, it will not use the path of ClassLibrary2.dll to load
ClassLibrary1.dll. Instead, it will look in current AppDomain's loaded
assemblies list first, it not found, then it will try to load from GAC.
(This is why I found previously that adding your WindwardReports.dll to GAC
will succeed)

2) LoadFile does not load files into the LoadFrom context.

This means assembly loaded with LoadFile cannot be used by furthre LoadFile
calls. In other words, if we call LoadFile("<path>\ClassLibrary1.dll")
first, then call LoadFile("<path>\ClassLibrary2.dll"), it still cannot find
ClassLibrary1.dll since it's not loaded into the context. However, if we
"Add Reference" to ClassLibrary1.dll first in the main application, then
further call to LoadFile("<path>\ClassLibrary2.dll") will succeed since the
assembly is already in the context. (This is why my test project fail to
reproduce the issue on the very beginning: since you mentioned that the
add-in is using the shared assembly, so my test project added a reference
to ClassLibrary1.dll in the main application.)

Therefore, the fix to your issue is to use LoadFrom instead of LoadFile.
However, LoadFrom will only load an assembly if it's not already loaded.
Following code will demostrate the point:

Assembly ass1 =
Assembly.LoadFrom(@"c:\test\ClassLibrary1\bin\x86\Debug\ClassLibrary1.dll");
Console.WriteLine(ass1.CodeBase);
Assembly ass2 =
Assembly.LoadFrom(@"c:\test\ClassLibrary2\bin\x86\Debug\ClassLibrary1.dll");
Console.WriteLine(ass2.CodeBase);

Above code will both print out
"c:\test\ClassLibrary1\bin\x86\debug\ClassLibrary1.dll", second call to
LoadFrom will not load it again from a second place. This is the case
"assemblies that have the same identities but with different paths".

Hope this helps.

Regards,
Walter Wang (wawang@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
David Thielen - 30 Jul 2007 16:14 GMT
Bingo - that all makes sense now. Thanks for digging in to this.

Signature

thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Cubicle Wars - http://www.windwardreports.com/film.htm

> Hi Dave,
>
[quoted text clipped - 64 lines]
>
> This posting is provided "AS IS" with no warranties, and confers no rights.
David Thielen - 26 Jul 2007 05:52 GMT
Got it!

Sample here - http://www.windwardreports.com/temp/LoadAssembly.zip

It fails if the bean is a J# dll. Works fine for a C# dll. Any ideas?

Signature

thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Cubicle Wars - http://www.windwardreports.com/film.htm

> Hi Dave,
>
[quoted text clipped - 40 lines]
>
> This posting is provided "AS IS" with no warranties, and confers no rights.
David Thielen - 27 Jul 2007 18:46 GMT
Ok, I have a sample with the problem at
http://www.windwardreports.com/temp/TestLoadAssembly.zip

The issue seems to be if there is a 4th dll with the interface definition.
Even if you put the InterfaceLib as a reference to MyEngine it still does not
find it.

Signature

thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Cubicle Wars - http://www.windwardreports.com/film.htm

> Hi Dave,
>
[quoted text clipped - 17 lines]
>
> This posting is provided "AS IS" with no warranties, and confers no rights.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.