C# 将自定义路径设置为引用的 DLL?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1892492/
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
Set Custom Path to Referenced DLL's?
提问by Metal450
I've got a C# project (call it MainProj
) which references several other DLL projects. By adding these projects to MainProj
's references, it will build them and copy their resulting DLL's to MainProj's working directory.
我有一个 C# 项目(称之为MainProj
),它引用了其他几个 DLL 项目。通过将这些项目添加到MainProj
的引用,它会构建它们并将它们生成的 DLL 复制到 MainProj 的工作目录。
What I'd like to do is have these referenced DLL's be located in a subdirectory of MainProj
's working directory, i.e. MainProj/bin/DLLs, rather than the working directory itself.
我想要做的是让这些引用的 DLL 位于MainProj
的工作目录的子目录中,即 MainProj/bin/DLLs,而不是工作目录本身。
I'm not a very experienced C# programmer, but coming from the C++ world, I'm assuming one approach would be to remove the project references and explicitly load the required DLL's by path and filename (i.e. in C++, LoadLibrary
). What I'd prefer to do however, if there's a way, would be to set some sort of "reference binary path", so they'd all be auto-copied to this subdir when I build (and then be referenced from there without me needing to explicitly load each). Is such a thing possible?
我不是一个非常有经验的 C# 程序员,但来自 C++ 世界,我假设一种方法是删除项目引用并通过路径和文件名(即在 C++ 中LoadLibrary
)显式加载所需的 DLL 。但是,如果有办法,我更愿意做的是设置某种“引用二进制路径”,这样当我构建时它们都会被自动复制到这个子目录(然后从那里被引用而无需我需要明确加载每个)。这样的事情可能吗?
If not, what's the preferred method in C# to accomplish what I'm after (i.e. something with Assembly.Load
/ Assembly.LoadFile
/ Assembly.LoadFrom
? Something in AppDomain
perhaps, or System.Environment
?)
如果不是,那么在 C# 中完成我所追求的首选方法是什么(即带有Assembly.Load
/ Assembly.LoadFile
/ 的Assembly.LoadFrom
东西?AppDomain
也许是什么,或者System.Environment
?)
采纳答案by Aaron
From this page(untested by me):
从这个页面(未经我测试):
Somewhere in your program's initialization (before you access any classes from a referenced assembly) do this:
在程序初始化的某个地方(在从引用的程序集中访问任何类之前)执行以下操作:
AppDomain.CurrentDomain.AppendPrivatePath(@"bin\DLLs");
Edit:This articlesays AppendPrivatePath is considered obsolete, but also gives a workaround.
编辑:这篇文章说 AppendPrivatePath 被认为已过时,但也提供了一种解决方法。
Edit 2:Looks like the easiest and most kosher way to do this is in the app.config file (see here):
编辑 2:看起来最简单和最犹太的方法是在 app.config 文件中(请参阅此处):
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin\DLLs" />
</assemblyBinding>
</runtime>
</configuration>
回答by Pedro77
From Tomekanswer at: Loading dlls from path specified in SetdllDirectory in c#
来自Tomek 的回答:从 c# 中 SetdllDirectory 中指定的路径加载 dll
var dllDirectory = @"C:/some/path";
Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + ";" + dllDirectory)
It works perfectly for me!
它非常适合我!
回答by 56ka
Here is an other way to proceed without using obsolete AppendPrivatePath
. It catches a kind of event "associated dll not found" (so it will be called only if the dll is not found in the default directory).
这是在不使用 obsolete 的情况下进行AppendPrivatePath
的另一种方法。它捕获一种事件“找不到关联的 dll”(因此只有在默认目录中找不到 dll 时才会调用它)。
Works for me (.NET 3.5, not tested other versions)
适用于我(.NET 3.5,未测试其他版本)
/// <summary>
/// Here is the list of authorized assemblies (DLL files)
/// You HAVE TO specify each of them and call InitializeAssembly()
/// </summary>
private static string[] LOAD_ASSEMBLIES = { "FooBar.dll", "BarFooFoz.dll" };
/// <summary>
/// Call this method at the beginning of the program
/// </summary>
public static void initializeAssembly()
{
AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs args)
{
string assemblyFile = (args.Name.Contains(','))
? args.Name.Substring(0, args.Name.IndexOf(','))
: args.Name;
assemblyFile += ".dll";
// Forbid non handled dll's
if (!LOAD_ASSEMBLIES.Contains(assemblyFile))
{
return null;
}
string absoluteFolder = new FileInfo((new System.Uri(Assembly.GetExecutingAssembly().CodeBase)).LocalPath).Directory.FullName;
string targetPath = Path.Combine(absoluteFolder, assemblyFile);
try
{
return Assembly.LoadFile(targetPath);
}
catch (Exception)
{
return null;
}
};
}
PS: I did not managed to use AppDomainSetup.PrivateBinPath
, it is too laborious.
PS:没用过AppDomainSetup.PrivateBinPath
,太费劲了。