AssemblyResolve事件未命中 [英] AssemblyResolve event not hit

查看:106
本文介绍了AssemblyResolve事件未命中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

我有一个依赖于子文件夹中存储的某些程序的应用程序.我想摆脱app.config文件(以及其中的privatePath ="MySubFolder"),并且不想将程序集安装到GAC中.

我想做的是使用AssemblyResolve事件来告诉应用程序在哪里寻找程序集.但是,当我运行该应用程序时,在执行命中AssemblyResolve处理程序之前,我得到FileNotFoundException.实际上,在发生其他任何事情之前,我都会收到该错误.我在应用程序的入口处放置了一个断点,并且在执行第一行代码之前就出现了异常.

.NET 3.5和4.0都是相同的.

任何建议都将受到高度赞赏.

Hi all,

I have an app that depends on some assemblies stored in a subfolder. I''d like to get rid of the app.config file (and the privatePath="MySubFolder" within) and I don''t want to install the assemblies into the GAC.

What I''m trying to do is to use the AssemblyResolve event to tell the app where to look for the assemblies. However, when I run the app I get a FileNotFoundException before the execution hits the AssemblyResolve handler. In fact I get that error before anything else happens. I placed a breakpoint on the entry point of the app and the exception comes before the very first line of code is executed.

This is the same with both .NET 3.5 and 4.0.

Any advice is highly appreciated.

推荐答案

似乎您不是在动态加载ClientClass.您可以检查是否正确引用了具有该类的dll吗?我的意思是版本和文件路径.您也可以尝试 Dependency Walker [ ^ ]).
It seems you are not loading ClientClass dynamically. Can you check if dll having that class is referenced correctly? I mean the version and file paths. You can also try Dependency Walker[^] if that helps.


您好.
我刚刚检查了代码并进行了测试,并提出了解决方案.问题在于该库需要在使用前加载到某个地方.但是,如果在Main中使用它,则应该在Main之前加载它(=在添加AppDomain.CurrentDomain.AssemblyResolve事件处理程序之前).您要做的就是将代码移到一个单独的过程中,从使用ClientClass的所有代码中清除Main,然后在Main中调用该过程,但是在创建事件处理程序之前无需这样做,就像这样:

Hi there.
I''ve just checked the code and tested, and came out with a solution. The problem is that the library needs to be loaded somewhere before it''s used. But if you use it in the Main then it should be loaded before the Main ( = before adding the AppDomain.CurrentDomain.AssemblyResolve event handler). All you have to do is move your code in a separate procedure cleaning your Main from all code that uses the ClientClass, then call that procedure in the Main, but not before creating the event handler, just like this:

static void Main(string[] args)
{
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
    UseClientClass();
    Console.ReadLine();
}
static void UseClientClass()
{
    Console.Write("Enter name: ");
    string name = Console.ReadLine();
    ClientClass.ClientClass clientClass = new ClientClass.ClientClass();
    Console.WriteLine(clientClass.SayHello(name));
}


有关该主题的MSDN帮助可能会引起误解.
您是否看到此代码示例:

http://www.thegecko.org/ [ ^ ]?




问题是,崩溃发生在之前 AppDomain.CurrentDomain.AssemblyResolve的处理程序甚至在main启动之前添加到事件调用列表中.

因此,该模式似乎无法真正起作用. (也许还需要更多研究.)
我会考虑做得很好的替代方案:使用动态加载的程序集.
请参见:
创建使用可重载插件的WPF应用程序... [ ^ ],
AppDomain拒绝加载程序集 [
MSDN help on the topic could look a bit misleading.
Did you see this code sample:

http://www.thegecko.org/[^]?




The problem is that the crash happens before the handler of AppDomain.CurrentDomain.AssemblyResolve even is added to the event invocation list, before start of main.

So, it looks like this schema does not really work. (Maybe it need some more research.)
I would consider well-working alternative: using dynamically loaded assemblies.
Please see this:
Create WPF Application that uses Reloadable Plugins...[^],
AppDomain refuses to load an assembly[^].

Some designs I described in the above Solutions are overly difficult or problematic. In your case you need the simplest of the cases: non-reloadable (loaded-once) plug-in, which is really simple.

You can use a simple extra trick: my schema suggests you create a plug-in interface, but you don''t want to add any shared libraries (you want all the libraries in one place, found by application). You can put this interface in the application: an application assembly (in EXE file) can be loaded exactly as a library, referenced by other assembly.



It was interesting exercise. :-)
As we face such difficulties, let''s do something more realistic.

Don''t you think you over-estimated the hassle of application config? Did you use probing.
option? Look at this sample file:

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



这意味着我将这个文件和我的应用程序放在某个目录中,并且我所有的库程序集都放在其子目录".\Mediasoft\Assembly"中,它们由我的某些应用程序共享,并在该子目录下自动解析.它不必是子目录,可以在目录结构的顶部.

—SA



It means that I place this file with my application in some directory, and all my library assemblies are put in its sub-directory ".\Mediasoft\Assembly", they are shared by some set of my applications and are automatically resolved under this sub-directory. It does not have to be a sub-directory, can be somewhere on top of directory structure.

—SA


这篇关于AssemblyResolve事件未命中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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