"Safe" GetType()?

  • Thread starter Thread starter Peter Andersen
  • Start date Start date
P

Peter Andersen

As can be seen in various threads in this an other
newsgroups, some of us are having problems with
Type.GetType() due to the following:

<quote>
If typeName includes only the name of the Type, this
method searches in the calling object's assembly, then in
the mscorlib.dll assembly.
If typeName is fully qualified with the partial or
complete assembly name, this method searches in the
specified assembly.
</quote>

The problem is, that this prevents use of Type.GetType()
for a type not used by the program attempting the lookup
unless you happen to know in which assembly to look for
it (you can then use Assembly.Load and Assembly.GetType).

So say, I want to look up the CodeBase of the type
System.Windows.Forms.Control in a non-graphics program.
This will fail unless I know the fully qualified name of
the assembly containing this type.

I know that if I use

Type.GetType(typeof(System.Windows.Forms.Control))

the C# compiler will find the assembly for me at compile
time, and it will work. But in the case I want to make a
tool that can look up an arbitrary type (e.g. specified
on command line), I cannot use this.

I have (to no avail) been seeking for some routine to
help me make such a tool. It may be that I should
call "gacutil -l" and analyze output(?) but are there
really no framework classes to allow me to do this?

In the apparent absense of such a routine, I have
attempted to write one myself. The code can be seen below.
It is slow and probably not the correct way to do it. Can
someone point out a better solution?

Example uses of this as a console tool:

$ gettype System.String
System.String codebase:
file:///c:/winnt/microsoft.net/framework/v1.1.4322/mscorli
b.dll
$ gettype System.ComponentModel.Component
System.ComponentModel.Component codebase:
file:///c:/winnt/microsoft.net/framework/v1.1.4322/system.
dll

Sincerely,
Peter Andersen,
Computer Science Department,
University of Aarhus,
Denmark.

gettype.cs:
===========

using System;
using System.Runtime.InteropServices;
using System.Reflection;
using System.IO;

public class GetType {
public static void Main(System.String[] args)
{
if (args.Length>0){
Console.WriteLine(args[0] + " codebase: ");
Type t = gettype(args[0]);
if (t != null){
Console.WriteLine(t.Assembly.CodeBase);
} else {
Console.WriteLine("Type " + args[0] + " not
found.");
}
}
}

static bool trace_runtime = false;

internal static Type gettype(String cls)
{
// First try Type.GetType.
// Searches in the calling object's assembly,
then in the mscorlib.dll
Type t = Type.GetType(cls);
if (t != null) return t;

// Then try by loading DLLs
// Can I search the GAC instead programmatically?
// Or is it better to exec "gacutil -l" and
analyze output?
String dir =
RuntimeEnvironment.GetRuntimeDirectory();
Assembly asm;
// First try obvious prefix as assembly
int dotpos = cls.LastIndexOf('.');
if (dotpos>0){
String firsttry = cls.Substring(0,dotpos);
if (trace_runtime) Console.WriteLine("[ first
try: " + firsttry + "]");
try {
asm = Assembly.LoadFile(dir +
Path.DirectorySeparatorChar + firsttry + ".dll");
t = asm.GetType(cls);
if (t != null){
if (trace_runtime) Console.WriteLine("
FOUND!");
return t;
}
} catch (Exception) {
// Ignore error and go on
}
}

// Then search all files in system runtime
directory (:-(
String[] dlls = Directory.GetFiles(dir, "*.dll");
for (int i=0; i<dlls.Length; i++){
if (dlls.EndsWith("mscorlib.dll"))
continue; // mscorlib already examined
if (trace_runtime) Console.WriteLine("
[searching " + dlls + "]");
try {
asm = Assembly.LoadFile(dlls);
t = asm.GetType(cls);
if (t != null){
if (trace_runtime) Console.WriteLine("
FOUND!");
return t;
}
} catch (Exception) {
// Ignore error and go on
}
}

// Giving up
return null;
}
 
Thanks - I have had a look at the KB article refered from
there, and I have also looked inside the sscli, and I can
see that there are som COM APIs that can be used.

But what I really would like is some .NET Framework
libraries to use directly in managed code.

Comparing to the Java world, I can always obtain type
information about any class that can be found in the
classpath via
Class cls = Class.forName(anyClassName);

It has come as a surprice to me how difficult this is to
accomplish using the .NET framework.
I know that the situation is simpler in the Java world
since the file name for the class is identical to the
class name, but still I am surpriced if there are no
managed APIs for doing e.g. what my home-made gettype
does (or e.g. a more advanced version that would respect
a given config file whan resolving type names to files).

Would anyone at MS comment on this?
Have I overlooked something?

/Peter Andersen
 
Back
Top