强制项目从当前目录加载DLL [英] Forcing project to load DLL's from the current directory

查看:122
本文介绍了强制项目从当前目录加载DLL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在试图通过强迫当前系统(而不是Windows目录)中的DLL加载并使用DLL来使该程序在每个操作系统上都能运行,但是它无法正常工作.我试图启用本地复制"并更改引用路径,但是没有成功,该程序尝试从Windows目录中加载DLL.
我的问题是:如何解决此问题?

I am trying to make a program that works on every operating system by forcing it to load and use the DLL''s in the current directory, not the windows directory, but it don''t works. I tried to enable "copy local" and change the refference path, but without any success, the program tries to load the DLL''s from the windows directory.
My question is: how can I fix this?

推荐答案

我不确定您是否了解操作系统的可移植性和可执行文件的解析顺序.您应该做相反的事情:绝对避免使用当前目录.可执行文件名不是通过当前目录解析的,也不是通过"Windows目录"解析的.实际上,Windows目录对于可执行文件名称路径是完全无关紧要的.程序集成功放到那里的唯一原因是因为您将此路径包括列表写入了PATH环境变量中.将其删除from PATH-基本上,所有内容都将继续正常运行.除了您的应用程序外,只是因为您输入的内容有误.

对于当前目录,每当应用程序更改当前目录时,如果路径中包含该目录,它的行为就如同它.同样,具有平台兼容性的情况与您所想的相反:对于类似Unix的系统,当前目录不在路径中,这就是为什么,例如,如果您需要在Windows中运行某些应用程序,文件app,您可以使用命令./app(不仅仅是app)启动它.当前目录还有另一个问题:您为什么认为它是什么?用户可以执行任何当前目录中的任何应用程序.因此,没有代码可以对当前目录进行任何假设.

运行时查找程序集的方式非常复杂:

http://msdn.microsoft.com/en-us/library/yx7xezcf%28v = vs.100%29.aspx [ ^ ].

在实践中,您可以使用两个规则.默认情况下,应用程序加载的所有程序集都在可执行目录中找到,即条目程序集主模块位置的目录.该目录与当前目录无关.顺便说一下,这是您在运行时可以找到此目录的方式:
I''m not sure you understand OS portability and executable file resolution order. You should do just the opposite: avoid using the current directory by all means. The executable file name is resolved not by using current directory, and not by "Windows directory". In fact, the Windows directory is totally insignificant to the executable name path; the only reason your assemblies put there are successfully resolved is because you have this path included list written in the PATH environment variable. Remove it from PATH — and, basically, everything will continue to work correctly. Except your application, just because you put it wrong.

As to the current directory, it behaves like it if is was included in the path every time an application change the current directory. Again, the situation with platform compatibility is just the opposite to what you think: with Unix-like system, the current directory is not in the path, that''s why, if you, for example, need to run some application in the file app, you start it with the command ./app, not just app. There is another problem with current directory: why do your think what it is? The user can execute any application in any current directory, any at all. So, no code should make any assumption about current directory.

The way runtime locates assemblies is pretty complex:

http://msdn.microsoft.com/en-us/library/yx7xezcf%28v=vs.100%29.aspx[^].

In practice, you can use two rules. By default, all assemblies loaded by application are found in the executable directory, that is, the directory of the location of a main module of entry assembly. This directory has nothing to do with the current directory. By the way, this is how you can find this directory during run-time:
string entryAssemblyLocation = System.Reflection.Assembly.GetEntryAssembly().Locationl
string executableDirectory = System.IO.Path.GetDirectoryName(entryAssemblyLocation);



非默认位置应解析.例如,如果您有多个使用某些通用代码库的应用程序,而又不想将它们放在不同的目录中,则不想放入GAC(以避免打扰安装/卸载),就是这种情况.

最通用的解决方法是使用事件System.AppDomain.AssemblyResolve:
http://msdn.microsoft.com/en-us/library/system.appdomain. assemblyresolve.aspx [ ^ ].

一种简单实用的解决方法是使用应用程序配置文件.考虑以下示例:



Non-default locations should be resolved. For example, this is the case when you have several application using some common code base you don''t want to put in GAC (to avoid bothering with installation/deinstallation), if you want to have the applications in different directories.

The very general way of resolution is using the event System.AppDomain.AssemblyResolve:
http://msdn.microsoft.com/en-us/library/system.appdomain.assemblyresolve.aspx[^].

One simple practical way of resolution is using the application config files. Consider this example:

<configuration>
	<runtime>
		<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
			<probing privatePath="..\MyClassLibraries"/>
		</assemblyBinding>
	</runtime>
</configuration>



这样,您可以拥有几个具有不同应用程序级程序集的单独目录,并且可以在一个或多个单独的库目录(例如".. \ MyClassLibraries")中找到一组通用的共享库.
有关程序集绑定重定向的更多选项和详细信息,请参见:
http://msdn.microsoft.com/en-us/library/2fc472t2%28v = vs.100%29.aspx [ ^ ],
http://msdn.microsoft.com/en-us/library/twy1dw1e%28v = vs.100%29.aspx [ ^ ].

—SA



This way, you can have several separate directories with different application-level assemblies, and the common set of shared libraries could be found in one or more separate library directories such as "..\MyClassLibraries".

For more options and detail on assembly binding re-direction, please see:
http://msdn.microsoft.com/en-us/library/2fc472t2%28v=vs.100%29.aspx[^],
http://msdn.microsoft.com/en-us/library/twy1dw1e%28v=vs.100%29.aspx[^].

—SA


您确定要使用的dll位于exe目录中吗?看看这篇文章 http://msdn.microsoft.com/zh-CN /library/7d83bc18(VS.80).aspx [
Are you sure the dll you want to use are in the exe''s directory? Take a look at this article http://msdn.microsoft.com/en-us/library/7d83bc18(VS.80).aspx[^]


这篇关于强制项目从当前目录加载DLL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆