gpt4 book ai didi

.net - 使用 CodeDomProvider 编译到内存时,程序集找不到引用的程序集

转载 作者:行者123 更新时间:2023-12-04 17:39:48 24 4
gpt4 key购买 nike

我正在尝试使用 CodeDomProvider 在运行时将一些代码编译到内存中。

我正在编译的代码引用了一个外部程序集,我将其包含在编译代码时使用的参数中。

当我编译到内存并尝试对 Visual Studio 加载项中生成的程序集使用反射时,它会抛出一个异常,指出它找不到引用的程序集。

(异常(exception))
“无法加载一种或多种请求的类型。检索 LoaderExceptions 属性以获取更多信息。”

(加载程序异常)
"{"无法加载文件或程序集 'Dynamo.Jiss.Task, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' 或其依赖项之一。系统找不到指定的文件。":"Dynamo.Jiss.Task, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"}"

我尝试使用绝对路径从不同的地方引用程序集。

如果从控制台应用程序运行完全相同的代码,它可以正常工作,如果我不编译到内存,它也可以在加载项中正常工作。
删除对外部程序集的引用和引用它的代码在编译到内存时也可以工作,因此它可能正如异常所描述的那样是加载引用的程序集的问题。

有谁知道为什么编译到内存和引用程序集在 Add-In 中不起作用?

它正在运行的 AppDomain 内是否有一些限制或我应该注意的一些限制? (我目前最好的猜测)

它应该在特定文件夹中吗?使用相对路径引用?安全设定?需要签名吗?有任何想法吗?

我想要实现的是一种将具有特定扩展名的文件放入项目中并让插件自动编译它的方法,如果它实现了 ITask 接口(interface)(来自外部程序集),它将调用一个 Setup() 方法,使它代码可以 Hook 到 Visual Studio 事件并在监听不同事件时执行任务/脚本。这样,如果另一个文件被更改,我可以轻松地执行文本模板,或者在不同的事件(文档保存、构建等)上合并和缩小文件。

这样的事情是否已经存在(以减轻我的痛苦)? :)

最佳答案

这很可能发生,因为您告诉 CodeDom 生成一个内存中的程序集(这确实是一个谎言,因为它临时生成到磁盘,加载它,然后删除文件)。关键是,CodeDom 程序集的编译目录与您用于编译它的目录不同。也就是说,如果您在 bin\Debug 中运行,则会将 CodeDom 程序集生成到 %temp%。

您可以通过我能想到的两种方式之一来解决这个问题:

  • 将 CodeDom 程序集编译到与执行程序集相同的路径。
    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");
  • 处理 AssemblyResolve 事件并向 CodeDom 程序集提供它所请求的引用程序集。
    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;
    }
    }
    }
  • 关于.net - 使用 CodeDomProvider 编译到内存时,程序集找不到引用的程序集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6804147/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com