So I dont know how to do that...
I have a program "Prg.cs" and a dll "Test.dll".
I have try:
Assembly asm=Assembly.Load(#"C:\Users\Me\documents\visual studio 2013\Projects\Prg\Prg\bin\Debug\Test.dll");
Type runApp = asm.GetType();
dynamic thisApp = Activator.CreateInstance(runApp, this);
But gives me error:
An unhandled exception of type 'System.IO.FileLoadException' occurred in mscorlib.dll
Additional information: Could not load file or assembly 'C:\\Users\\Me\\documents\\visual studio 2013\\Projects\\Prg\\Prg\\bin\\Debug\\Test.dll' or one of its dependencies. The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)
Thanks!
You can do something like this:
class Program
{
static void Main(string[] args)
{
var dll = Assembly.LoadFile(#"C:\Test.dll");//The path of your dll
var theType = dll.GetType("dll.Test");
var c = Activator.CreateInstance(theType);
var method = theType.GetMethod("Output");//Your method in the class
method.Invoke(c, new object[]{#"Hello world"});
Console.ReadLine();
}
}
this link can help youstackoverflow.com/a/18362515/3383479
Related
in library
public string GetName()
{
ResourceLoader rl = ResourceLoader.GetForCurrentView("ClassLibrary1/Resources");
return rl.GetString("Name");
}
at "ResourceLoader rl = ResourceLoader.GetForCurrentView("ClassLibrary1/Resources");"
An exception of type 'System.Runtime.InteropServices.COMException' occurred in ClassLibrary1.dll but was not handled in user code
WinRT information: 未找到 ResourceMap。
Additional information: 未找到 ResourceMap。
未找到 ResourceMap。
If there is a handler for this exception, the program may be safely continued.
if i add reference this library , it is working well.
but i Dynamic reference this library ,it is failure.
Assembly assembly = Assembly.Load(new AssemblyName("ClassLibrary1"));
if (assembly == null)
{
return;
}
Type type = assembly.GetType("ClassLibrary1.Class1");
ICore core = Activator.CreateInstance(type) as ICore;
textBlock1.Text = core.GetName();
//ClassLibrary1.Class1 c1 = new ClassLibrary1.Class1();
//textBlock1.Text = c1.GetName(); //it is working well
how to use resources for Dynamic reference in the library?
if i add reference this library , it is working well. but i Dynamic reference this library ,it is failure.
Most of your code is right, you didn't mention what exactly the exception is. Here is my demo:
Portable class library, class1:
public class Class1
{
public Class1()
{
Debug.WriteLine("ClassLib Loaded!");
}
public void Output()
{
Debug.WriteLine("ClassLib method!");
}
}
In UWP app:
Assembly assembly = Assembly.Load(new AssemblyName("ClassLibrary1"));
if (assembly == null)
{
return;
}
Type type = assembly.GetType("ClassLibrary1.Class1");
object obj = Activator.CreateInstance(type);
var method = type.GetMethod("Output");
method.Invoke(obj, null);
The output in the immediate window is like this:
To do this, you will need to:
build your class library.
right click your class lib, choose "Open folder in File Explorer", in the folder find the "bin" folder => "Debug", copy the ClassLibrary1.dll into your UWP project like this:
Although doing this can solve the problem, but in my personal opinion, it seems not easier than directly adding reference of this library.
We try to compile source code at runtime and then add the resulting assembly to an AppDomain. But in the moment even loading the assembly fails:
string sourceCode = "using System;\r\n" +
"public class Program1{\r\n" +
" public static void Main1(){\r\n" +
" int i = 100;\r\n" +
" }\r\n" +
"}";
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
Assembly[] assembliesOfCurrentDomain = AppDomain.CurrentDomain.GetAssemblies();
for (int runAssembliesInCurrDomain = 0; runAssembliesInCurrDomain < assembliesOfCurrentDomain.Length; runAssembliesInCurrDomain++)
{
try
{
parameters.ReferencedAssemblies.Add(assembliesOfCurrentDomain[runAssembliesInCurrDomain].Location);
}
catch
{
}
}
// True - memory generation, false - external file generation
parameters.GenerateInMemory = false;
parameters.OutputAssembly = "D:\\temp\\123.dll";
parameters.IncludeDebugInformation = true;
parameters.ReferencedAssemblies.Add(Assembly.GetEntryAssembly().Location);
// True - exe file generation, false - dll file generation
parameters.GenerateExecutable = false;
CompilerResults results = provider.CompileAssemblyFromSource(parameters, sourceCode);
Assembly a = Assembly.Load("D:\\temp\\123.dll");
The last line throws an exception "An unhandled exception of type 'System.IO.FileLoadException' occurred in mscorlib.dll". We have no idea what's going wrong there. We tried compiling this code with .Net Framework 2.0 and 4.5, with AnyCPU, x64, and x86. Always the same problem. Any ideas why this exception is be thrown?
You have to use the Assembly.LoadFrom method to load from a path. It will throw an exception that it is not recommended to do so but this exception is caught internally and programm succeeds.
From the MSDN article you should be passing in the long name of the assembly to Assembly.Load. For example:
string longName = "123, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
Assembly assem = Assembly.Load(longName);
During my studies of reflection, I have encountered the .net module.
I understand that means I can compile a single class as .net module (correct me if I wrong) then load this compiled .net module using Assembly.LoadModule(string,byte[]).
I wrote a class that look like this:
using System;
using System.Text;
public class Mycs {
public static string GiveString(){
return "Hello World !";
}
}
and compiled it using the switch "/target:module" using this code:
CodeDomProvider CDP = CodeDomProvider.CreateProvider("CSharp");
CompilerParameters CP = new CompilerParameters();
CP.GenerateExecutable = false;
CP.CompilerOptions = "/target:module";
CP.OutputAssembly = FilePathText.Text.Replace(Strings.Right(FilePathText.Text, 3), ".netmodule");
string source = File.ReadAllText(FilePathText.Text);
CompilerResults RS = CDP.CompileAssemblyFromSource(CP, source);
I then retrieved the resulted file bytes:
byte[] b = File.ReadAllBytes(FilePathText.Text);
And finally I tried to load the module to the current executed assembly:
Module[] Modules = Assembly.GetExecutingAssembly().GetModules();
Module[] moduless = Assembly.GetExecutingAssembly().GetLoadedModules();
Module A = Assembly.GetExecutingAssembly().LoadModule(Modules[0].Name, b);
Whether I passed the Modules[0].Name or moduless[0].Name both cause this exception:
An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll
Additional information: Invalid file name
Why do I get this invalid file name error?
You cannot load dynamically created module to an existing assembly, assemblies once compiled are immutable.
My best guess is that you need to use AssemblyBuilder.DefineDynamicModule() to create your classes in it. In this case you the type you created will be loaded automatically. or compile your classes as assemblies, not the modules, and load those assemblies dynamically using Assembly.LoadFile method.
Can someone please explain what is happening to me? I have a test project that tests a dummy instance of my service. In the test project, I simply reference the dummyService.exe and System.SystemProcess dll.
In my dummyService project however, I have referenced the class library, which itself uses other dlls from other componentsn as well as other projects in my solution.
The problem is that when I run my test, exceptions get thrown( First Chance exceptions for dlls which are loaded and working in the dummyService), in addition invalidcast exception (error message below).
Unable to cast object of type 'Export.CaseOutputGenerator' to type 'Export.ICaseOutputGenerator'.
System.InvalidCastException was caught
Message=Unable to cast object of type 'Export.CaseOutputProcess.CustomCaseOutputGenerator' to type
'Export.CaseOutputProcess.ICaseOutputGenerator'.
Source=Export.CaseOutputProcess
StackTrace:
at Export.CaseOutputProcess.CaseOutputGeneratoryFactory.GetCaseOutputGeneratorObject(String assemblyName, String className)
in C:\Monitor\Export.CaseOutputProcess\CaseOutputGeneratoryFactory.cs:line 56
at Monitor.BOMock.GenerateCaseOutput(String OutputFolder, String iFile, Int32 seqNum, DataTable CaseSettings, String SettingFileName)
in C:\Monitor\BOMock\BOMock.cs:line 1069
at Monitor.BOMock.Handling() in C:\Monitor\BOMock\BOMock.cs:line 492 InnerException:
public static ICaseOutputGenerator GetCaseOutputGeneratorObject(string assemblyName, string className)
{
ICaseOutputGenerator customeOutputGen = null;
var obj = GetObject(assemblyName, className);
if (obj != null)
caseOutputGen = (ICaseOutputGenerator)obj; // FAILS HERE
return caseOutputGen;
}
private static object GetObject(string fullName, string className)
{
try
{
Type caseOutputGen = null;
var localAssembly = Assembly.LoadFrom(fullName);
foreach (var testType in localAssembly.GetTypes())
{
if (!testType.FullName.EndsWith(className, StringComparison.InvariantCultureIgnoreCase)) continue;
caseOutputGen = testType;
break;
}
if (caseOutputGen == null) return null;
var obj = Activator.CreateInstance(caseOutputGen);
return obj;
}
catch (FileNotFoundException ex)
{
throw new Exception("Failed to load assembly: " + Environment.NewLine + fullName, ex);
}
catch (Exception ex)
{
throw new Exception("Failed to load assembly: " + Environment.NewLine + fullName, ex);
}
}
Where assemblyName is the Path to the dll file to load and className happens to be the name of the class to create an instance of.
In the code, as you see, using reflection I load the assembly at the assemblyName PATH provided (String assemblyName) http://msdn.microsoft.com/en-us/library/system.reflection.assembly.loadfrom.aspx , and then using reflection again, I then create an instance of the className (String className ) contained in the loaded assembly. http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx
How do I remedy this problem please? I don't want to have to reference all my dlls in the test project. How do I get around or solve this problem please?? Thanks in advance.
Based on that stack trace, it looks like the assembly where the type lives is not being found. If you just add the reference to the compiled exe, you're probably not going to get the other libraries along with it. I think you've got a couple of choices:
Go ahead and bite the bullet: add the references to the other libraries in your test project. They're typically not transitive: just because your service knows about them doesn't necessarily follow that your test's assembly knows about them as well.
Add a post-compilation step to your test's project that copies over the other assemblies so that they can be found by the app domain running your test.
Use dependency injection and an inversion of control container. There are quite a few out there, but Castle Windsor, StructureMap and Unity come to mind. Scott Hanselman's got a great list of them on his blog: http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx
How can I verify if dll was wrote in .net? I'm using code as below:
Assembly assembly = null;
try
{
foreach (string fileName in Directory.GetFiles(Environment.CurrentDirectory.ToString(), "*.dll", SearchOption.TopDirectoryOnly))
{
try
{
assembly = Assembly.LoadFrom(fileName);
Console.WriteLine(fileName);
}
catch (Exception ex)
{
...
}
finally
{
...
}
}
}
catch (ReflectionTypeLoadException ex)
{
..
}
When I want to load assembly = Assembly.LoadFrom(fileName) non-.net dll, an exception will appear:
Could not load file or assembly 'file:///...' or one of its dependencies.
The module was expected to contain an assembly manifest.
I want to use verify in if-else clause.
Can you help me?
There's a helper function in the .NET bootstrapper DLL that you can use. Mscoree.dll exports GetFileVersion(), a helper that returns the CLR version that an assembly needs. That function is going to fail when the file isn't an assembly and does so without raising an exception.
It should look like this:
using System;
using System.Text;
using System.Runtime.InteropServices;
public class Utils {
public static bool IsNetAssembly(string path) {
var sb = new StringBuilder(256);
int written;
var hr = GetFileVersion(path, sb, sb.Capacity, out written);
return hr == 0;
}
[DllImport("mscoree.dll", CharSet = CharSet.Unicode)]
private static extern int GetFileVersion(string path, StringBuilder buffer, int buflen, out int written);
}
You can do the following trick :
try {
Assembly assem = Assembly.LoadFile(filePath);
}
catch (BadImageFormatException e) {
//NOT .NET ASSEMBLY
}
In practice if on assembly load you recieve BadImageFormatException , that means that assembly is not formatted in CLR assembly way.
Hine form MSDN link:
The exception that is thrown when the file image of a dynamic link
library (DLL) or an executable program is invalid.
If you do not need to load the assembly in the current domain, I suggest to use:
using System.Reflection;
public class AssemblyName_GetAssemblyName
{
public static void Main()
{
// Replace the string "MyAssembly.exe" with the name of an assembly,
// including a path if necessary. If you do not have another assembly
// to use, you can use whatever name you give to this assembly.
//
try
{
AssemblyName myAssemblyName = AssemblyName.GetAssemblyName("MyAssembly.exe");
}
catch (BadImageFormatException ex)
{
...
}
}
}
The best way to know it, without to throw an exception, is to parse the OptionalImageFileHeader of the PE and look at the DataDirectory for CLR Header.
Currently I working on it, because I had the same issue..