OK - the solution (possibly not the most performant - but this is a UI for
support staff!).
[code]
public class AssemblyViewer : MarshalByRefObject
{
#region Constructor
public AssemblyViewer()
{
_dumbAssemblies = new Dictionary<string, AssemblyBuilder>();
}
#endregion
#region Methods
public List<string> GetTypes(string asmFile)
{
Assembly asm = this.LoadAssemblyForViewFrom(asmFile);
List<string> ret = new List<string>();
// here go the types that could be loaded
foreach (Type type in asm.GetTypes())
{
if (type != null)
ret.Add(type.FullName);
}
return ret;
}
#endregion
#region Event handlers
private Assembly CurrentDomain_AssemblyResolve(object sender,
ResolveEventArgs args)
{
AssemblyBuilder ab =
AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(args.Name),
AssemblyBuilderAccess.Run);
_dumbAssemblies.Add(args.Name, ab);
return ab;
}
#endregion
#region Supplementary
private void GenerateDumbType(string asm, string typeName)
{
AssemblyBuilder ab;
if (_dumbAssemblies.TryGetValue(asm, out ab))
{
ModuleBuilder module = ab.GetDynamicModule(asm);
if (module == null)
module = ab.DefineDynamicModule(asm);
TypeBuilder tb = module.DefineType(typeName,
TypeAttributes.Public);
tb.CreateType();
}
}
private Assembly LoadAssemblyForViewFrom(string asmFile)
{
Assembly asm = Assembly.LoadFrom(asmFile);
AppDomain.CurrentDomain.AssemblyResolve += new
ResolveEventHandler(CurrentDomain_AssemblyResolve);
try
{
asm.GetTypes();
}
catch (ReflectionTypeLoadException e)
{
// here are the unresolved ones
if (e.LoaderExceptions != null)
{
foreach (TypeLoadException exc in e.LoaderExceptions)
{
string missedAsmName = (string)typeof
(TypeLoadException).GetField("AssemblyName", BindingFlags.Instance |
BindingFlags.NonPublic).GetValue(exc);
GenerateDumbType(missedAsmName, exc.TypeName);
}
}
}
finally
{
AppDomain.CurrentDomain.AssemblyResolve -= new
ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
return asm;
}
#endregion
#region Fields
private Dictionary<string, AssemblyBuilder> _dumbAssemblies;
#endregion
}
[/code]
Useage of this (from main application):
[code]
string filename = @"c:\stagingDir\MyPlugin.dll";
AppDomain app2 = AppDomain.CreateDomain("Resolver");
AssemblyViewer ins = (AssemblyViewer)
app2.CreateInstanceAndUnwrap
("ReflectingNoDependencies", "ReflectingNoDependencies.AssemblyViewer");
List<string> types = ins.GetTypes(filename);
foreach (string s in types)
{
Console.WriteLine(s);
}
AppDomain.Unload(app2);
[/code]
and there we have it.
===================================
This list is hosted by DevelopMentorĀ® http://www.develop.com
View archives and manage your subscription(s) at http://discuss.develop.com