C# 在运行时加载程序集并使用 Activator.CreateInstance() 创建实例

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12317553/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 22:52:07  来源:igfitidea点击:

Loading assemblies at runtime and creating instances using Activator.CreateInstance()

c#.netreflection

提问by Dave New

I am trying to load an assembly at runtime, and I'm unsure as to why I can't create an instance of a type in the assembly using the static Activator.CreateInstance(). It works with Assembly.CreateInstance().

我正在尝试在运行时加载一个程序集,但我不确定为什么我不能使用 static 在程序集中创建一个类型的实例Activator.CreateInstance()。它适用于Assembly.CreateInstance().

string assemblyFilename = "MyAssembly.dll";
string assemblyName = "MyAssembly";
string typeName = "MyAssembly.MyType";

FileInfo fileInfo = new FileInfo(assemblyFilename);

This works:

这有效:

var assembly = Assembly.LoadFrom(assemblyFilename);
Form form = (Form)assembly.CreateInstance(typeName);

But this does NOT work:

但这不起作用:

Assembly.LoadFrom(assemblyFilename);
Form form = (Form)Activator.CreateInstance(assemblyName, typeName).Unwrap();

FileNotFoundException thrown:

FileNotFoundException 抛出:

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

无法加载文件或程序集“MyAssembly”或其依赖项之一。该系统找不到指定的文件。

EDIT:

编辑:

In both cases, after the Assembly.LoadFrom()call, I can see that my assembly has been loaded when I look in AppDomain.CurrentDomain.GetAssemblies().

在这两种情况下,在Assembly.LoadFrom()调用之后,当我查看AppDomain.CurrentDomain.GetAssemblies().

采纳答案by armen.shimoon

You have to first load the assembly into your current AppDomain:

您必须首先将程序集加载到您当前的 AppDomain 中:

AppDomain.CurrentDomain.Load(File.ReadAllBytes(assemblyFileName));

EDIT: Does this work?

编辑:这行得通吗?

Form form = (Form)Activator.CreateInstance(Type.GetType(typeName))

回答by Aghilas Yakoub

You can adjust your file with his path

你可以用他的路径调整你的文件

var path = Assembly.GetAssembly(MyType.GetType()).Location;
var thisAssembly= Assembly.LoadFrom(path);

var TypeName = "";
Type type = thisAssembly.GetType(TypeName);
object instance = Activator.CreateInstance(type);

回答by A Khudairy

Tried to edit original answer but i got no response from author. So just in case some one needs this, here is the code that worked for me

试图编辑原始答案,但我没有得到作者的回应。所以以防万一有人需要这个,这是对我有用的代码

System.Reflection.Assembly assembly = AppDomain.CurrentDomain.Load(File.ReadAllBytes("DLL_PATH"));  
Form form = (Form)assembly.CreateInstance("FullNameSpace.ClassName");

回答by DeltaPng

A variation of A Khudairy's answer here to allow passing in input parameters to access a specific constructor, plus this variation of his answer resolved a problem which I've had and literally been searching on and off for several weeks now trying to resolve (many kudos to him for sharing the answer).

A Khudairy 的答案的变体在这里允许传入输入参数以访问特定的构造函数,加上他的答案的变体解决了一个问题,这个问题我已经并且实际上已经搜索了几个星期现在试图解决(很多荣誉给他分享答案)。

My problem was I wanted to load a .NET 3.5 dll into a new application which was .NET 4.6, but those old dll's used third party controls which looked to use CAS policy. I'd get an error from the third party controls saying I needed to turn in app.config, if I did that I could load and run the files just fine if they were on my local computer, but if I tried to load them from a network drive, which I need to do, then I got a FileIOPermission error.

我的问题是我想将 .NET 3.5 dll 加载到 .NET 4.6 的新应用程序中,但那些旧的 dll 使用了第三方控件,这些控件看起来使用 CAS 策略。我会从第三方控件收到一个错误,说我需要打开 app.config,如果我这样做了,如果它们在我的本地计算机上,我可以加载和运行这些文件,但是如果我尝试从一个我需要做的网络驱动器,然后我收到了 FileIOPermission 错误。

Tried running combinations of NetFx40_LegacySecurityPolicy with loadFromRemoteSources and useLegacyV2RuntimeActivationPolicy, and tried several different methods such as Activator.CreateInstance() which usually works for me, tried creating a sandbox (though I don't know if I did it properly), but nothing would work, except for below. Note, my user controls were also based off of a base class. I had run some CAS command prompt commands prior to grant access to the network drive, and my app should be running in full trust. Regardless, it didn't look like any of the methods I had tried other than this one has worked so far for me.

尝试运行 NetFx40_LegacySecurityPolicy 与 loadFromRemoteSources 和 useLegacyV2RuntimeActivationPolicy 的组合,并尝试了几种不同的方法,例如通常对我有用的 Activator.CreateInstance(),尝试创建一个沙箱(虽然我不知道我是否做得正确),但没有任何效果,以下除外。请注意,我的用户控件也基于基类。在授予对网络驱动器的访问权限之前,我已经运行了一些 CAS 命令提示符命令,并且我的应用程序应该在完全信任的情况下运行。无论如何,它看起来不像我尝试过的任何方法,除了这个方法到目前为止对我有用。

The code fix:

代码修复:

object dllUserControl = null;
System.Reflection.Assembly assembly = AppDomain.CurrentDomain.Load(File.ReadAllBytes("DLL_PATH"));  
dllUserControl = assembly.CreateInstance("FullNameSpace.ClassName",true,BindingFlags.Default,null,constructorParams[],null,null);

... from which I could later cast the object as needed (to my base class) to later launch it in it's own Form/Window.

...从中我可以稍后根据需要将对象(到我的基类)转换为稍后在它自己的窗体/窗口中启动它。