汇编时,汇编与编码的编码时,无法找到引用的组件
-
25-10-2019 - |
题
我正在尝试使用CodedomProvider在运行时编译一些代码。
我正在编译的代码对我在编译代码时使用的参数中包含的外部组件有一个引用。
当我编译到内存并尝试在Visual Studio加载项中生成的组件上使用反射时,它会引发异常,说它找不到引用的组件。
(例外)
“无法加载一种或多种请求的类型。检索LoadereXceptions属性以获取更多信息。”
(Loaderexception)
“ {”无法加载文件或汇编'dynamo.jiss.task,版本= 1.0.0.0,culture =中性,publickeytoken = null'或其依赖项之一。系统找不到指定的文件。
我尝试使用绝对路径从不同位置引用组件。
如果它是从控制台应用程序运行的,则完全相同的代码正常工作,如果我不编译内存,则在加载项中也可以正常工作。
删除对外部组件的引用以及引用其在编译内存时也可以工作的代码,因此,它可能是例外描述的问题是加载引用的汇编的问题。
有人知道为什么要编译内存和引用组件在加载项中不起作用吗?
它正在运行的AppDomain中是否有一些限制或我应该知道的内容? (我目前最好的猜测)
应该在特定文件夹中吗?使用相对路径引用?安全设定?需要签名吗?有任何想法吗?
我要实现的目标是一种在项目中使用特定扩展程序的文件,并让Addin自动编译它,并且如果它实现ITASK接口(来自外部组件),它将调用一个使其成立的setup()方法在聆听不同事件时,代码可以将代码连接到Visual Studio事件并执行任务/脚本。这样,如果更改了另一个文件,我可以轻松地执行文本模板,或在不同事件(保存文档,构建等)上组合和缩小文件。
这样的事情已经存在(以减轻我的痛苦)吗? :)
解决方案
这很可能发生,因为您要告诉编码要生成内存组件(这确实是一个谎言,因为它临时生成磁盘,加载它,然后删除文件)。关键是,编码组件的编译目录与您要编译的编码的编译目录不同。也就是说,如果您在bin debug中运行,则代码组件的生成为%temp%。
您可以通过我能想到的两种方式之一解决此问题:
将编码组件编译到与执行程序集相同的路径上。
myCodeProvider.GenerateInMemory = false; // may not be necessary...haven't tried this in a while myCodeProvider.OutputAssembly = string.Format(@"{0}\{1}", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location, "mydll.dll");
处理汇编固定事件,并提供编码组件,其要求的引用组件。
AppDomain.CurrentDomain.AssemblyResolve += OnCurrentDomainAssemblyResolve private static Assembly OnCurrentDomainAssemblyResolve(object sender, ResolveEventArgs args) { // this is absurdly expensive...don't do this more than once, or load the assembly file in a more efficient way // also, if the code you're using to compile the CodeDom assembly doesn't/hasn't used the referenced assembly yet, this won't work // and you should use Assembly.Load(...) foreach (Assembly @assembly in AppDomain.CurrentDomain.GetAssemblies()) { if (@assembly.FullName.Equals(args.Name, StringComparison.OrdinalIgnoreCase)) { return @assembly; } } }