C# .NET 再次在运行时加载程序集
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/468243/
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
.NET Load assemblies at runtime Again
提问by MegaByte
I posted a similar question a time ago. I need to load an assembly at runtime.
我前一段时间发布了一个类似的问题。我需要在运行时加载程序集。
This is easy if I know the absolute path of the dll at runtime.
如果我在运行时知道 dll 的绝对路径,这很容易。
But I dont :( The assembly.Load() or LoadFromFile() fails if the file is not in the application root.
但我不会 :( 如果文件不在应用程序根目录中,则 assembly.Load() 或 LoadFromFile() 会失败。
The only thing I have is the dll name. The dll could be located in the root, system32 or in even in the GAC.
我唯一拥有的是dll名称。dll 可以位于 root、system32 甚至 GAC 中。
Is it possible for .net to automatically determine where the dll is at, like for example : it should first look in the root. If its not there move on to the system folders, else try the GAC.
.net 是否可以自动确定 dll 所在的位置,例如:它应该首先查看根目录。如果它不在那里移动到系统文件夹,否则尝试 GAC。
EDITED
已编辑
I am using plug-in architecture. I do not need to register the dll. I have a multi user application. I have a applications table containing information regarding applications. Each application has a dll path associated with it, containing certain algorithms associated with that app. Hope this helps.
我正在使用插件架构。我不需要注册dll。我有一个多用户应用程序。我有一个包含有关应用程序信息的应用程序表。每个应用程序都有一个与之关联的 dll 路径,其中包含与该应用程序关联的某些算法。希望这可以帮助。
回答by Ed S.
The dll will be found automatically is it is in some location referenced in the PATH system variable (i.e., system32) or if the dll is registered. You can't find it if it can be anywhereon disk, but no one needs that functionality anyway.
如果 dll 位于 PATH 系统变量(即 system32)中引用的某个位置,或者该 dll 已注册,则会自动找到该 dll。如果它可以在磁盘上的任何位置,您就无法找到它,但无论如何都没有人需要该功能。
EDIT: can the dll's be registered? how are you getting the assembly name if you don't know of the assembly ahead of time? Are you creating some type of plug-in architecture? I think it would help if you explained your situation a bit more.
编辑:可以注册dll吗?如果您事先不知道程序集,您如何获得程序集名称?您是否正在创建某种类型的插件架构?我认为如果你多解释一下你的情况会有所帮助。
EDIT2: If that is the case, why not provide a way for the user to register his or her plug in? You can get all the information that you need from an open file dialog. That or simply make them dump it into a folder that you specify.
EDIT2:如果是这样,为什么不为用户提供一种注册他或她的插件的方法呢?您可以从打开的文件对话框中获取所需的所有信息。或者只是让他们将其转储到您指定的文件夹中。
回答by abatishchev
Register this assembly into the GAC. How to do that
将此程序集注册到 GAC。怎么做
回答by lubos hasko
You can hook up into AppDomain.CurrentDomain.AssemblyResolve
event and load the assembly for your application manually on demand.
您可以连接到AppDomain.CurrentDomain.AssemblyResolve
事件并按需手动加载应用程序的程序集。
回答by Lonzo
Yes there is a way and it depends on whether your dll is weakly(without a public key token) or strongly(with a public key token) named. If its weakly named and you have added a reference to the assembly with the dll within VS, then VS will first look in the application folder root and if it does not find it, it will then look in the subdirectories that you specify as the value of the privatePath attribute in your XML config file.
是的,有一种方法,这取决于您的 dll 是弱命名(没有公钥令牌)还是强命名(带有公钥令牌)。如果它的名称很弱,并且您在 VS 中添加了对带有 dll 的程序集的引用,那么 VS 将首先在应用程序文件夹根目录中查找,如果找不到它,它将在您指定为值的子目录中查找XML 配置文件中的 privatePath 属性。
If its a strongly named dll, then the CLR will search in the GAC so you need to install the dll in the GAC. The CLR can also look in the application directory if you install an XML config file that has its codeBase element pointing to the dll's path.
如果它是一个强命名的dll,那么CLR 会在GAC 中搜索,因此您需要在GAC 中安装该dll。如果您安装的 XML 配置文件的 codeBase 元素指向 dll 的路径,CLR 还可以查看应用程序目录。
To specify an assembly in the GAC you can use the /reference:[DLL name] switch when compiling your assembly.
要在 GAC 中指定程序集,您可以在编译程序集时使用 /reference:[DLL name] 开关。
回答by Gishu
I hope you've read up on the following. My suggestion...
我希望你已经阅读了以下内容。我的建议...
- How the runtime locates assemblies
- You can give Assembly.LoadWithPartialNamea whirl.. might work.. it says it will search the application folder and the GACunlike Assembly.Load. (However its less safe.. coz you might end up with the wrong version of the DLL since you dont specify all 4 parts of the Assembly Name)
- Also try AppDomainSetup.PrivateBinPath (AppDomain.AppendPrivatePath has been deprecated in favor of this) to add subfolders of the application root to the list of folders to probe assemblies for. You can also try copying over files from other places into a [AppFolder]\MySandboxForDLLsToLoad, which is added to the PrivateBinPath.
- 运行时如何定位程序集
- 你可以给Assembly。LoadWithPartialNamea whirl.. 可能会起作用..它说它将搜索应用程序文件夹和 GAC,与 Assembly.Load 不同。(但是它不太安全......因为你最终可能会得到错误版本的 DLL,因为你没有指定程序集名称的所有 4 个部分)
- 还可以尝试 AppDomainSetup.PrivateBinPath(AppDomain.AppendPrivatePath 已被弃用以支持此功能)将应用程序根目录的子文件夹添加到要探测程序集的文件夹列表中。您还可以尝试将文件从其他位置复制到 [AppFolder]\MySandboxForDLLsToLoad,该文件已添加到 PrivateBinPath。
回答by Gishu
Use this Assembly.LoadWithPartialName(assemblyName);
使用这个 Assembly.LoadWithPartialName(assemblyName);
回答by Chris Kooken
When the current application looks for assemblies, it looks in several locations (bin folder, gac, etc..) if it can not find one, then the developer needs to manually tell the application where to look. You can do this by intercepting the AssemblyResolve event, and using the event args to tell the CLR where your assembly is.
当前应用程序查找程序集时,会在多个位置(bin 文件夹、gac 等)中查找,如果找不到,则开发人员需要手动告诉应用程序去哪里查找。您可以通过拦截 AssemblyResolve 事件并使用事件参数告诉 CLR 您的程序集所在的位置来完成此操作。
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
....................
Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
var strTempAssmbPath=
Path.GetFullPath("C:\Windows\System32\" + args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll");
var strTempAssmbPath2=
Path.GetFullPath("C:\Windows\" + args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll");
if (File.Exists(strTempAssmbPath))
return Assembly.LoadFrom(strTempAssmbPath);
if (File.Exists(strTempAssmbPath2))
return Assembly.LoadFrom(strTempAssmbPath2);
}
回答by Leyu
回答by Jane
The resolution algorithm used by .NET to find the assemblies and their dependents is straight forward.
.NET 用于查找程序集及其依赖项的解析算法很简单。
- .NET identifies the required version. Usually the information about the dependant assemblies is present in the application's assembly manifest.
- .NET searches GAC (Global Assembly Cache), only if the assembly is strong named.
- If not found in GAC, and if a .config file presnt, then .NET searches the location specified in the cofiguration file, else .NET searches directory containing the executable (.EXE)
- After this, If the assembly is still not found, the application terminates with error.
- .NET 标识所需的版本。通常,有关依赖程序集的信息存在于应用程序的程序集清单中。
- .NET 搜索 GAC(全局程序集缓存),仅当程序集是强命名的。
- 如果在 GAC 中找不到,并且存在 .config 文件,则 .NET 搜索配置文件中指定的位置,否则 .NET 搜索包含可执行文件 (.EXE) 的目录
- 在此之后,如果仍未找到程序集,应用程序将因错误而终止。
Click herefor the video explaining the .net resolution algorithm, and click herefor a video on late binding assemblies