How to check if a certain assembly exists? - c#

I'm using the Activator to instantiate a new class based on the short name of an assembly (e.a. 'CustomModule'). It throws a FileNotFoundException, because the assembly isn't there. Is there a way to check if a certain assembly name is present?
I'm using the following code:
System.Runtime.Remoting.ObjectHandle obj =
System.Activator.CreateInstance(assemblyName, className);
The main objective is to rather test for the presence of the assembly than to wait for the exception to occur.

If you'll notice my comment to your question it will be evident that I'm not rightly sure exactly how you want or need to go about this, but until we have a more elaborate description I can only offer you this in the hope it fits well to your situation (the key is in 'searching' the assemblies):
var className = "System.Boolean";
var assemblyName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
var assembly = (from a in assemblies
where a.FullName == assemblyName
select a).SingleOrDefault();
if (assembly != null)
{
System.Runtime.Remoting.ObjectHandle obj =
System.Activator.CreateInstance(assemblyName, className);
}
.NET 2.0 Compatible Code
Assembly assembly = null;
var className = "System.Boolean";
var assemblyName = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
{
if (a.FullName == assemblyName)
{
assembly = a;
break;
}
}
if (assembly != null)
{
System.Runtime.Remoting.ObjectHandle obj =
System.Activator.CreateInstance(assemblyName, className);
}
If you want to determine whether or not the file exists before trying to load it (a good practice) then, given you have its name and know the desired location, simply try to find the file when the assembly is being resolved:
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
var className = "StackOverflowLib.Class1";
var assemblyName = "StackOverflowLib.dll";
var currentAssemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var obj = Activator.CreateInstance(Path.Combine(currentAssemblyPath, assemblyName), className);
static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
var currentAssemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
if (File.Exists(Path.Combine(currentAssemblyPath, args.Name)))
{
return Assembly.LoadFile(Path.Combine(currentAssemblyPath, args.Name));
}
return null;
}

I think it is better not to try to avoid the exception. The reason is that if you have code like
if (DoesAssemblyExist(asmName)) {
object = Activator.CreateInstance(typeName);
}
else {
MessageBox.Show("Assembly does not exist");
}
there is always a risk in a pre-emptive multitasking OS that the assembly might be added/removed between the check and the actual creation. Yes, I realize this risk is minimal, but I still think the exception variant looks better because it is atomic.

Missing assembly definitely constitutes an exception, try/catch FileNotFoundException and handle the situation as per your logic.

I hope it will help for someone in the future:
On every external .dll you are using, create its own uniqe key, like so:
string key = "fjrj3288skckfktk4owoxkvkfk4o29dic";
And then, when you load your form, for every single external .dll that you have got, simply check if the key is exists like so:
If(isMyLib.Variables.key == key)
// continue
else
// .dll does not exists or broken.

Related

"Could not load file or assembly" when the referenced dll file is in the loaded assemblies [duplicate]

This question already has an answer here:
Could not load file or assembly error on GetTypes method
(1 answer)
Closed 1 year ago.
The structure of my solution is as follows:
I got 2 projects. Independent of each other at compile time (no cross references). The second one is a class library that is loaded at runtime from the first one.
That library has its own dll dependencies, which I guess is what causes the exception thrown when I'm trying to do execute code using these dlls. I supposed that these referenced dlls are probably not loaded at runtime, except from the class library dll. Therefore, I added some code to load the referenced assemblies before executing any code of the loaded assembly.
To my surprise the "problematic" dll is already included in the loaded assemblies when the following code is executed, its location is correct, but the error still occurs and I have no idea how to further troubleshoot the issue.
Any help is highly appreciated.
try
{
Assembly a = Assembly.LoadFile(Path.GetFullPath(filename));
//Try to find the type the derived plugin class
foreach (Type t in a.GetTypes())
{
if (t.IsSubclassOf(typeof(PluginBase)))
{
Console.WriteLine("Plugin class detected! {0}", t.Name);
//Get Referenced Assemblies
AssemblyName[] l = a.GetReferencedAssemblies()
//Get Loaded Assemblies
var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (AssemblyName a2 in l)
{
var asm = loadedAssemblies.FirstOrDefault(a => a.FullName == a2.FullName);
if (asm == null)
{
Assembly test = null;
try
{
//First try to load using the assembly name just in case its a system dll
test = Assembly.Load(a2);
//Try to load the assemly from the plugin directory
if (test == null)
{
test = Assembly.LoadFrom(Path.Join(a.Location, a2.Name + ".dll"));
}
}
catch
{
Callbacks.Log($"Unable to load assembly {a2.Name}", LogVerbosityLevel.WARNING);
}
if (test != null)
{
Callbacks.Log($"Loaded Assembly {a2.Name}", LogVerbosityLevel.WARNING);
AppDomain.CurrentDomain.Load(test.GetName());
}
}
}
object c = Activator.CreateInstance(t, new object[] { this });
Plugins[Path.GetFileName(filename)] = c as PluginBase;
//Call Dll initializers
t.GetMethod("OnLoad").Invoke(c, new object[] { });
break;
}
}
}
catch (Exception ex)
{
Log("Error during loading of plugin " + filename, LogVerbosityLevel.INFO);
Log("Exception type " + ex.Data, LogVerbosityLevel.INFO);
}
Aight, I think I figured it out. So before the reason why I saw the referenced assemblies loaded was because I iteratively loaded them by browsing in a dll folder that contains the class library + its references. The main problem is that I am so stupid that I forgot to load them to the AppDomain calling AppDomain.CurrentDomain.Load(assemblyname). However when I did try to fix that I realized that trying to just fetch the related AssemblyName object does not work. I get the same FileNotFoundException.
What fixed the issue was to use Assembly.LoadFrom instead of Assembly.LoadFile. I read through the documentation that it states that LoadFile treats the loaded assemblies differently regardless if they are exactly the same dll file just in different location. In my case there is only a single path that I tried to load the assembly from, but I guess that LoadFile also differentiates the loaded assemblies in this case as well. However, I am still not sure why trying to use an AssemblyName coming from LoadFile crashes compared to what comes out of LoadFrom. I would expect that they would be identical...
I also added a failsafe mechanism to try and load only the desired dll files. I just expect that all dlls that will be loaded will be prepended with a text identifier. So at first the desired dll is loaded and before invoking any code, its references are loaded using the AssemblyName object or the actual path if the first fails.
Everything seems to be running nicely till now so hopefully this solves it.
foreach (string filename in Directory.GetFiles("Plugins"))
{
if (!filename.EndsWith(("dll")))
continue;
if (!Path.GetFileName(filename).StartsWith(("Test")))
continue;
var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
//Load Assembly
try
{
Assembly a = Assembly.LoadFrom(Path.GetFullPath(filename));
AppDomain.CurrentDomain.Load(a.GetName());
//Try to find the type the derived plugin class
foreach (Type t in a.GetTypes())
{
if (t.IsSubclassOf(typeof(PluginBase)))
{
Console.WriteLine("Plugin class detected! {0}", t.Name);
//Load Referenced Assemblies
AssemblyName[] l = a.GetReferencedAssemblies();
loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (AssemblyName a2 in l)
{
var asm = loadedAssemblies.FirstOrDefault(a => a.FullName == a2.FullName);
if (asm == null)
{
Assembly test = null;
try
{
//First try to load using the assembly name just in case its a system dll
test = Assembly.Load(a2);
}
catch (FileNotFoundException ex)
{
try
{
Callbacks.Log($"Unable to load assembly {a2.Name}, Looking in plugin directory...", LogVerbosityLevel.WARNING);
test = Assembly.LoadFrom(Path.Join(Path.GetDirectoryName(a.Location), a2.Name + ".dll"));
} catch (Exception ex2)
{
Callbacks.Log($"Unable to load assembly {a2.Name}, Error: {ex2.Message}", LogVerbosityLevel.WARNING);
}
}
if (test != null)
{
Callbacks.Log($"Loaded Assembly {a2.Name}", LogVerbosityLevel.WARNING);
AppDomain.CurrentDomain.Load(test.GetName());
}
}
}
object c = Activator.CreateInstance(t, new object[] { this });
Plugins[Path.GetFileName(filename)] = c as PluginBase;
//Call Dll initializers
t.GetMethod("OnLoad").Invoke(c, new object[] { });
break;
}
}
}
catch (Exception ex)
{
Log("Error during loading of plugin " + filename, LogVerbosityLevel.INFO);
Log("Exception type " + ex.Data, LogVerbosityLevel.INFO);
}
}

.NET Core Assembly.LoadFile at PostBuild event

I need generate typescript files from some of my C# classes after build.
I created dotnet cli tool and added post-build event
dotnet tsgenerator "$(TargetPath)"
where $(TargetPath) is macros pointing, for example, D:\Test\bin\Release\netcoreapp2.0\my.dll
Next, i tried to load assembly next way:
public static void Main(string[] args)
{
var dllPath = args[0]; // "D:\Test\bin\Release\netcoreapp2.0\my.dll"
var assembly = Assembly.LoadFile(dllPath);
var types = assembly.GetExportedTypes(); // Throws exception
}
But i got ReflectionTypeLoadException that says Could not load file or assembly for some references assemblies (for example, Microsoft.AspNetCore.Antiforgery).
How i can load assembly for .NET Core applications?
I'm found solution at github issue. Message by amits1995 and angelcalvasp.
I'm added <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> to my csproj and using this code to load assembly:
public static class AssemblyLoader
{
public static Assembly LoadFromAssemblyPath(string assemblyFullPath)
{
var fileNameWithOutExtension = Path.GetFileNameWithoutExtension(assemblyFullPath);
var fileName = Path.GetFileName(assemblyFullPath);
var directory = Path.GetDirectoryName(assemblyFullPath);
var inCompileLibraries = DependencyContext.Default.CompileLibraries.Any(l => l.Name.Equals(fileNameWithOutExtension, StringComparison.OrdinalIgnoreCase));
var inRuntimeLibraries = DependencyContext.Default.RuntimeLibraries.Any(l => l.Name.Equals(fileNameWithOutExtension, StringComparison.OrdinalIgnoreCase));
var assembly = (inCompileLibraries || inRuntimeLibraries)
? Assembly.Load(new AssemblyName(fileNameWithOutExtension))
: AssemblyLoadContext.Default.LoadFromAssemblyPath(assemblyFullPath);
if (assembly != null)
LoadReferencedAssemblies(assembly, fileName, directory);
return assembly;
}
private static void LoadReferencedAssemblies(Assembly assembly, string fileName, string directory)
{
var filesInDirectory = Directory.GetFiles(directory).Where(x => x != fileName).Select(x => Path.GetFileNameWithoutExtension(x)).ToList();
var references = assembly.GetReferencedAssemblies();
foreach (var reference in references)
{
if (filesInDirectory.Contains(reference.Name))
{
var loadFileName = reference.Name + ".dll";
var path = Path.Combine(directory, loadFileName);
var loadedAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(path);
if (loadedAssembly != null)
LoadReferencedAssemblies(loadedAssembly, loadFileName, directory);
}
}
}
}
Usage:
public static void Main(string[] args)
{
var dllPath = args[0]; // "D:\Test\bin\Release\netcoreapp2.0\my.dll"
var assembly = AssemblyLoader.LoadFromAssemblyPath(dllPath);
var types = assembly.GetExportedTypes(); // No exceptions
}
Well you are able to load assembly but GetTypes() and GetExportedTypes() depend on the public classes within that assembly, if they have external references you get this exception.
Answer:
This means the Types of that assembly depend on other assembly which the current .NetCore does not have access at the run time because it can not connect to other dependent assemblies
Solution:
Get dependencies of the DLL assemblies and compile all of them, then load each assembly iteratively to get all ExportedTypes (i.e publicly visible Types)
Code:
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using Microsoft.Extensions.DependencyModel;// add this nuget
class Program
{
static void Main(string[] args)
{
var asl = new AssemblyLoader();
var asm = asl.LoadFromAssemblyPath(#"C:\temp\Microsoft.AspNetCore.Antiforgery.dll");
try
{
var y = asm.GetExportedTypes();
Console.WriteLine(y);
}
catch (Exception e1)
{
Console.WriteLine("Got exception at first attempt of GetExportedTypes ");
Console.WriteLine("\t*********" + e1.Message + "**************");
var deped = asl.CallForDependency(asm.GetName());
try
{
Console.WriteLine("\n" + deped.ToString());
Console.WriteLine("----------All Exported Types------------");
foreach (var item in deped.ExportedTypes)
{
Console.WriteLine(item);
}
}
catch (Exception e2)
{
Console.WriteLine("Got exception at second attempt of GetExportedTypes ");
Console.WriteLine("\t*********" + e2.Message + "**************");
}
}
Console.ReadLine();
}
}
public class AssemblyLoader :AssemblyLoadContext
{
protected override Assembly Load(AssemblyName assemblyName)
{
var deps = DependencyContext.Default;
var res = deps.CompileLibraries.Where(d => d.Name.Contains(assemblyName.Name)).ToList();
var assembly = Assembly.Load(new AssemblyName(res.First().Name));
return assembly;
}
public Assembly CallForDependency(AssemblyName assemblyName)
{
return this.Load(assemblyName);
}
}
Output :
Got exception at first attempt of GetExportedTypes
*********Could not load file or assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. An operation is not legal in the current state. (Exception from HRESULT: 0x80131509)**************
Microsoft.AspNetCore.Antiforgery, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
----------All Exported Types------------
Microsoft.Extensions.DependencyInjection.AntiforgeryServiceCollectionExtensions
Microsoft.AspNetCore.Antiforgery.AntiforgeryOptions
Microsoft.AspNetCore.Antiforgery.AntiforgeryTokenSet
Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException
Microsoft.AspNetCore.Antiforgery.IAntiforgery
Microsoft.AspNetCore.Antiforgery.IAntiforgeryAdditionalDataProvider
Microsoft.AspNetCore.Antiforgery.Internal.AntiforgeryFeature
Microsoft.AspNetCore.Antiforgery.Internal.AntiforgeryOptionsSetup
Microsoft.AspNetCore.Antiforgery.Internal.AntiforgerySerializationContext
Microsoft.AspNetCore.Antiforgery.Internal.AntiforgerySerializationContextPooledObjectPolicy
Microsoft.AspNetCore.Antiforgery.Internal.AntiforgeryToken
Microsoft.AspNetCore.Antiforgery.Internal.BinaryBlob
Microsoft.AspNetCore.Antiforgery.Internal.CryptographyAlgorithms
Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgery
Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgeryAdditionalDataProvider
Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgeryTokenGenerator
Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgeryTokenSerializer
Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgeryTokenStore
Microsoft.AspNetCore.Antiforgery.Internal.DefaultClaimUidExtractor
Microsoft.AspNetCore.Antiforgery.Internal.IAntiforgeryFeature
Microsoft.AspNetCore.Antiforgery.Internal.IAntiforgeryTokenGenerator
Microsoft.AspNetCore.Antiforgery.Internal.IAntiforgeryTokenSerializer
Microsoft.AspNetCore.Antiforgery.Internal.IAntiforgeryTokenStore
Microsoft.AspNetCore.Antiforgery.Internal.IClaimUidExtractor
Reference and explanation on ReflectionTypeLoadException:
Assembly.GetTypes Method ()
ReflectionTypeLoadException
The assembly contains one or more types that cannot be loaded. The
array returned by the Types property of this exception contains a Type
object for each type that was loaded and null for each type that could
not be loaded, while the LoaderExceptions property contains an
exception for each type that could not be loaded.
Remarks
The returned array includes nested types.
If the GetTypes method is called on an assembly and a type in that
assembly is dependent on a type in an assembly that has not been
loaded (for example, if it derives from a type in the second
assembly), a ReflectionTypeLoadException is thrown. For example, this
can happen if the first assembly was loaded with the
ReflectionOnlyLoad or ReflectionOnlyLoadFrom methods, and the second
assembly was not loaded. It can also happen with assemblies loaded
using the Load and LoadFile methods if the second assembly cannot be
located when the GetTypes method is called.
Note
If a type has been forwarded to another assembly, it is not included
in the returned array. For information on type forwarding, see Type
Forwarding in the Common Language Runtime.
Linked :
How to load assemblies located in a folder in .net core console app
How to dynamically load assemblies in dotnet core
Try the LoadFrom method for loading in the assembly, rather than LoadFile:
public static void Main(string[] args)
{
var dllPath = args[0]; // "D:\Test\bin\Release\netcoreapp2.0\my.dll"
var assembly = Assembly.LoadFrom(dllPath);
var types = assembly.GetExportedTypes(); // Throws exception
}
You will also need to add the same references that are in the ddl file to your current project, so that the types are defined.

Proper way to resolving assemblies from subfolders

Here is how my application folders looks like:
Application:
+ App.exe
+ App.exe.config
Application/Plugins:
+ Plugin1 (folder)
Application/Plugins/Plugin1:
+ Plugin1.dll
+ SomeDll.dll
So main application App.exe looking for plugins folder and load {PluginName}.dll into memory to run it. This plugin usually uses it's own dependant assemblies which must be loaded (like SomeDll.dll). It appears that it make serious troubles sometimes. I receive exception that for example dependant assembly of dependant assembly cannot be found and I don't know why.
For example, My plugin must load lots of additional dlls becouse plugin runs OwinSelfHost service.
So it must load for example:
System.Web.Http.Owin
Owin
Microsoft.Owin
Microsoft.Owin.Host.HttpListener
Microsoft.Owin.Hosting
and when load Microsoft.Owin.Hosting then throw exception that cannot load Microsoft.Owin
Exception looks like:
Could not load file or assembly 'Microsoft.Owin, Version=2.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of it's dependencies. File not found.
I wrote this method to resolve assemblies. It is tweaked to fit my needs.
It basically hooks a AssemblyResolve event to the current application domain to retrieve an requested assembly from a list of directories.
There is no easy way to find where the assembly file that match the namespace to resolve, except by loading an assembly file and check to which namespace it belongs to.
Plus, it discards some unwanted assemblies (like serializers, resources...) and detects dlls or exes that are not .NET assemblies.
A better approach would consist in using the Global Assembly Cache, but we want our plugins to be fully moveable. So here it is.
public static class AssemblyResolver
{
internal static void Hook(params string[] folders)
{
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
// Check if the requested assembly is part of the loaded assemblies
var loadedAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.FullName == args.Name);
if (loadedAssembly != null)
return loadedAssembly;
// This resolver is called when an loaded control tries to load a generated XmlSerializer - We need to discard it.
// http://connect.microsoft.com/VisualStudio/feedback/details/88566/bindingfailure-an-assembly-failed-to-load-while-using-xmlserialization
var n = new AssemblyName(args.Name);
if (n.Name.EndsWith(".xmlserializers", StringComparison.OrdinalIgnoreCase))
return null;
// http://stackoverflow.com/questions/4368201/appdomain-currentdomain-assemblyresolve-asking-for-a-appname-resources-assembl
if (n.Name.EndsWith(".resources", StringComparison.OrdinalIgnoreCase))
return null;
string assy = null;
// Find the corresponding assembly file
foreach (var dir in folders)
{
assy = new[] { "*.dll", "*.exe" }.SelectMany(g => Directory.EnumerateFiles(dir, g)).FirstOrDefault(f =>
{
try { return n.Name.Equals(AssemblyName.GetAssemblyName(f).Name, StringComparison.OrdinalIgnoreCase); }
catch (BadImageFormatException) { return false; /* Bypass assembly is not a .net exe */ }
catch (Exception ex) { throw new ApplicationException("Error loading assembly " + f, ex); }
});
if (assy != null)
return Assembly.LoadFrom(assy);
}
throw new ApplicationException("Assembly " + args.Name + " not found");
};
}
}
Here is how it works:
AssemblyResolver.Hook("\Plugins", "\CommonReferences");
Everytime some assemblies needs to be resolved, it will get the one that is loaded in memory, otherwise it will search in any given folders.
You can use "AssemblyResolve Event" (Method 3):
https://support.microsoft.com/en-us/kb/837908

The fastest way to read assemblies GUID from Assembly Manifest file

I try to get GUID from many assemblies.
I chose the same way as Reflector read GUID - but so far it is extremely slow process. Moreover,I receive many exceptions, when some (connected) dll files are missing
Assembly CurrentDomain_ReflectionOnlyAssemblyResolve(object sender, ResolveEventArgs args)
{
string missedAssemblyFullName = args.Name;
Assembly assembly = Assembly.ReflectionOnlyLoad(missedAssemblyFullName);
return assembly;
}
//... and code
string exe = "test.exe";
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve +=CurrentDomain_ReflectionOnlyAssemblyResolve;
Assembly assembly = null;
if (assembly != null)
{
assembly = Assembly.ReflectionOnlyLoadFrom(exe);
if (assembly != null)
{
var test = CustomAttributeData.GetCustomAttributes(assembly);
foreach (var elem in test)
{
if (elem.AttributeType.Name == "GuidAttribute")
assemblyGuid = (string)elem.ConstructorArguments[0].Value;
}
}
}
How can I make a GUID reading process faster?
Is there any other way? I just want to open manifest file and read the same GUID which is available in AssemblyInfo.cs file [assembly: Guid("98c11478-7295-4c10-a97f-4b6805df6191")
Do I need ReflectionOnlyLoad method?
You can check out the code by Vijay Mukhi, who wrote his version of ILDASM (source code included). It parses the manifest of an assembly prett much the same way Microsoft's ILDASM does. You can then trim the code down to just the functionality you need.

Could not load file or assembly or one of its dependencies. The system cannot find the file specified

I have a code like this
public static Type ToType(XmlSerializableType xmlSerializableType)
{
string func = "XmlSerialzationType.ToType";
Type type = null;
if (xmlSerializableType != null && xmlSerializableType.Name != string.Empty)
{
type = Type.GetType(xmlSerializableType.Name);
if (type == null)
{
// May be a user defined class
try
{
Assembly assembly = Assembly.Load(xmlSerializableType.AssemblyName);
type = assembly.GetType(xmlSerializableType.Name);
}
catch (Exception ex)
{
TestDebug.DebugTraceSevere(func, "Exception " + ex.ToString());
}
}
}
return type;
}
I have a base class named "leaf" and a userdefinedclass named "roundedtree"
when 'xmlSerializableType.Name' becomes userdefined class '_rounded_tree', first time i am getting value for 'assembly as _rounded_treeGOLD, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' and so for 'type as {Name = "_rounded_tree" FullName = "_rounded_tree"}'. But after saving if i restart my application i cannot load value for 'assembly' getting exception 'Could not load file or assembly '_rounded_treeGOLD, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.":"_rounded_treeGOLD, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' and return type becomes null this should not happen
For baseclass "leaf" no issuses i will get xmlSerializableType.Name as " Root.Systemmodel.leaf" and 'type' becomes {Name = "leaf" FullName = "Root.Systemmodel.leaf"} assembly will be Root.Systemmodel, Version=8.0.7.0, Culture=neutral, PublicKeyToken=83bd062a94e26d58
What should i do in these circumstances
This is a bit of code which will generate assembly for userdefined class
public Type CreateType()
{
string func = "ManagedClass.CreateType";
// Create instances of AssemblyBuilder and ModuleBuilder for the new Type
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName();
// Create the assembly name by appending the machine name to the typename.
myAsmName.Name = this.TypeName + Environment.MachineName;
// Define assembly that can be executed but not saved
this.UserClassAssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.Run);
// Create dynamic module with symbol information
this.UserClassModuleBuilder = this.UserClassAssemblyBuilder.DefineDynamicModule("userdefinedmodule", true);
UPDATE
probably my assembly is creating for userdefined class but not saving that may be the reason i am not facing any issue first time, once i close the application i will lose that one see my code
// Define assembly that can be executed but not saved
this.UserClassAssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName,
AssemblyBuilderAccess.Run);
how to overcome this situation
UPDATE
Here my database is xml files. When i checked for base class leaf i can see the entry is <Name>Root.Systemmodel.WindowsSystem</Name><AssemblyName>Root.Systemmodel, Version=8.0.7.0, Culture=neutral, PublicKeyToken=83bd062a94e26d58</AssemblyName> in this case if restart my application no issues, but for user defined class "roundedtree" xml entry is <Name>_rounded_tree</Name> <AssemblyName>_rounded_treeGOLD, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</AssemblyName>
Here first time no issues, but if i restart my application i am getting exception
it happens because maybe the assembly you're going to load references to the another assembly that not exist in the same directory or system directory put all assembly in same folder
I,ve just copy paste my code but its clear
private string asmBase;
public Type[] GetAllTypeinAssembly(string assemblyName)
{
asmBase = System.IO.Path.GetDirectoryName(assemblyName);
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
System.Reflection.Assembly asm = System.Reflection.Assembly.Load(System.IO.File.ReadAllBytes(assemblyName));//domain.Load(bt) ;//
return asm.GetTypes();
}
private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
//This handler is called only when the common language runtime tries to bind to the assembly and fails.
//Retrieve the list of referenced assemblies in an array of AssemblyName.
Assembly MyAssembly, objExecutingAssemblies;
string strTempAssmbPath = "";
objExecutingAssemblies = args.RequestingAssembly;
AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies();
//Loop through the array of referenced assembly names.
foreach (AssemblyName strAssmbName in arrReferencedAssmbNames)
{
//Check for the assembly names that have raised the "AssemblyResolve" event.
if (strAssmbName.FullName.Substring(0, strAssmbName.FullName.IndexOf(",")) == args.Name.Substring(0, args.Name.IndexOf(",")))
{
//Build the path of the assembly from where it has to be loaded.
strTempAssmbPath = asmBase + "\\" + args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll";
break;
}
}
//Load the assembly from the specified path.
MyAssembly = Assembly.LoadFrom(strTempAssmbPath);
//Return the loaded assembly.
return MyAssembly;
}
I had the same issue, if you are working on SharePoint, sometime the references might not get bundled in WSP so, while deploying, these referenced dlls will not be deployed. Resolution is to manually these from the GAC or force these into WSPs or copy them to the local bin. The last one solved for me.

Categories

Resources