ReflectionTypeLoadException, question

  • Thread starter Thread starter Jim Butler
  • Start date Start date
J

Jim Butler

I am building a utility that will peruse a directory and
will update db tables that will house information about
all of our assemblies. It works fine except for this
error when i use either Assembly LoadFrom/LoadFile for
dll's that don't have all their dependent files listed in
that particular directory (this is true for our gac
files). The information i want to collect is name,
version, class, basetype, refname, refversion (stored in
multiple tables). Is there a way to get the info other
than loading the assembly. I noticed that ildasm has no
problem getting the info from the metadata or is there an
easier way of doing this?

sample below
Dim a1 As [Assembly] = [Assembly].LoadFile("c:\mydll.dll")

Dim t As Type
' error on line below
For Each t In a1.GetTypes()
Debug.WriteLine(t.FullName & "; " & t.BaseType().ToString)
Next t
Dim a As AssemblyName
For Each a In a1.GetReferencedAssemblies()
Console.WriteLine(a.Name() & "; " & a.Version.ToString)
Next

thanks,

jim
 
Hi Jim,

Thanks for your post. As I understand, the problem you are facing is that
you program fails to load the assembly when its underlying components are
missing so that you cannot use reflection to get its informations. Please
correct me if there is any misunderstanding. I am not performing research
on how to work around this problem, and I will update you with you findings.

Have a nice day!

Regards,

HuangTM
Microsoft Online Partner Support
MCSE/MCSD

Get Secure! -- www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
yes, that is exactly my problem, i know ildasm will do it, but i what i am
building (hopefully) is an automated object heirarchy/checker which will
then allow me to query "touch points" for all of our code and object
heirarchies. ie if you change this assembly, you will need possibly need to
test all of these other assemblies because they either inherit from that
assembly or reference it.

thanks, jim
 
Hi Jim,

Thanks for your response. In addition to System.Reflection classes, there
are equivalent unmanaged metadata APIs we can use. Acutally ILDasm uses the
unmanaged metadata APIs. Please refer to the MSDN article below for
detailed information and a sample project:

TypeRefViewer Utility Shows TypeRefs and MemberRefs in One Convenient GUI
http://msdn.microsoft.com/msdnmag/issues/01/11/hood/

Hope this helps.

Regards,

HuangTM
Microsoft Online Partner Support
MCSE/MCSD

Get Secure! -- www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
well, i've investigated the code from the sample more. It is still doing
the assembly.load, thus i still get the type load exception
here is the partial source

// If we have the name of the assembly DLL containing the
// Type, create a partially qualified name. The
// Type.GetType() method (below) works better this way!
if ( tr.m_strAssemblyName.Length > 0 )
{
Assembly ass = Assembly.LoadWithPartialName( tr.m_strAssemblyName );
String x = ass.FullName;
strQualifiedTypeName = tr.m_strTypeName + "," + x;// tr.m_strAssemblyName;
}

do you know of anywhere else i can look

thanks, jim
 
Hi Jim,

With Assembly.Load, you are still using System.Reflection instead of
unmanaged metatdata APIs. I reviewed the source code carefully, and it
imports meta data in unmanaged way like the following:

//----------------code snippet--------------
MetaDataImportWrapper::MetaDataImportWrapper( LPCSTR pszFileName ) :
m_pIMetaDataDispenser( 0 ),
m_pIMetaDataImport( 0 ),
m_pIMetaDataAssemblyImport( 0 )
{
CoInitialize( 0 );

HRESULT hr;

// Create the IMetaDataDispenser instance. We need this to create
// the IMetaDataImport and IMetaDataAssemblyImport interfaces
hr = CoCreateInstance( CLSID_CorMetaDataDispenser, 0,
CLSCTX_INPROC_SERVER,
IID_IMetaDataDispenser,
(LPVOID *)&m_pIMetaDataDispenser );
if ( FAILED(hr) )
throw "Unable to create IMetaDataDispenser";

wchar_t wszFileName[MAX_PATH];
mbstowcs( wszFileName, pszFileName, lstrlen(pszFileName)+1 );

// Create the IMetaDataImport interface
hr = m_pIMetaDataDispenser->OpenScope( wszFileName, ofRead,
IID_IMetaDataImport,
(LPUNKNOWN *)&m_pIMetaDataImport );
if ( FAILED(hr) )
throw "Unable to create IID_IMetaDataImport";
......
//----------------end of--------------------

You can download the whole project from the following article by the same
author. The ReflectMeta project is using System.Reflection, while Meta
project is calling the unmanaged metadata APIs.

Avoiding DLL Hell: Introducing Application Metadata in the Microsoft .NET
Framework
http://msdn.microsoft.com/msdnmag/issues/1000/metadata/default.aspx

Please let me know the result.

Have a nice day!

Regards,

HuangTM
Microsoft Online Partner Support
MCSE/MCSD

Get Secure! -- www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
Thanks for all the help, i think i will probably write one through the
unmanaged api in my spare time (as soon as i get some:). For my purpose
here, i will just make the assembly run on the server instead of my client
machine where it should have access to all the obects , thus allowing me to
use the reflection class (they will either be in the gac on the server or in
the respective bin directory). and if i hit an error log it so we can
report and find out what the problem is.

Thanks again

jim
 
Back
Top