【问题标题】:How to pick up an sgen-generated XmlSerializer DLL for a DLL rather than an EXE?如何为 DLL 而不是 EXE 获取 sgen 生成的 XmlSerializer DLL?
【发布时间】:2018-02-17 16:28:45
【问题描述】:

我有一个名为ess.exe 的可执行文件。我使用sgen.exe为其生成了一个XmlSerializer DLL,当我运行它时,它会获取生成的ess.XmlSerializers.dll,一切都很好。

我还有一个名为EntrianSourceSearch_14.dll 的DLL,它是使用Assembly.LoadFrom(DllPathname) 动态加载的。如果我为那个 DLL 生成一个 XmlSerializer DLL,它不会拾取生成的 DLL;相反,它会退回到 XML 序列化代码的运行时生成。

如何让我的 DLL 获取其相应生成的 XmlSerializer DLL?

编辑:我无法将 XmlSerializer DLL 放入可执行文件的目录中,因为我的 DLL 是 Visual Studio 扩展的一部分 - 可执行文件是 Visual Studio (devenv.exe),将我的产品片段复制到其目录中可能会被视为反社会。 :-)

编辑以添加更多上下文:这是一个 Visual Studio 插件扩展。它适用于 2005 年至 2017 年的所有 Visual Studio 版本。大部分代码安装到 Program Files 中,而旧版本的 Visual Studio 只需从那里作为加载项加载它。对于不支持插件的较新版本的 Visual Studio,有一个扩展,它只是 Program Files 中这些主要组件的加载器。该扩展使用LoadFrom 加载这些主要组件,其中之一是EntrianSourceSearch_14.dll

【问题讨论】:

  • 您可以在this post 中看到加载程序集的代码的 sn-p。注意对 Assembly.Load() 的调用,它不会在 LoadFrom() 所做的同一目录中查找。您可以使用 Fuslogvw.exe 进行验证。考虑将 xmlserializers.dll 程序集移动到与 exe 相同的目录中。
  • @HansPassant:感谢您的解释以及程序集加载代码的链接。关于“将 xmlserializers.dll 程序集移动到与 exe 相同的目录”,DLL 是 Visual Studio 扩展的一部分,因此可执行文件是 Visual Studio (devenv.exe)。将我的产品部分复制到其目录中可能会被视为反社会!
  • 诸如此类的重要细节属于问题,而不是评论。尽可能多地添加上下文信息。然后还有一些。
  • 您是否尝试过挂钩AppDomain.AssemblyResolve 事件msdn.microsoft.com/en-us/library/… 看看是否可以在询问时传递信息?
  • 伙计们,请记住,OP 在记录问题方面做得很差。这是一个 VS 扩展,它不应该使用 LoadFrom,因为所有二进制文件都必须由扩展安装程序部署。但无论是插件还是 VSIX 扩展,使用的是什么 VS 版本,这是否只是为了调试代码而进行的 hack,都只是盲目猜测。

标签: c# .net dll xml-serialization xmlserializer


【解决方案1】:

如果您已经构建和部署了签名的序列化程序集,则可以在加载和缓存序列化程序时添加 CurrentlDomain.AssemblyResolve 处理程序,例如:

    private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        var codeBase = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath;
        var serializerPath = Path.Combine(Path.GetDirectoryName(codeBase), new AssemblyName(args.Name).Name + ".dll");
        if (File.Exists(serializerPath))
            return Assembly.LoadFrom(serializerPath);
        else
            return null;
    }

但是,我找不到一种简单的方法将序列化程序集的部署包含在单程序集 VS 扩展中。

我确实找到了一种可能更可取的替代方法。它避免了直接调用Assembly.LoadFrom和上面代码中的一些假设:

  • 将使用 Xml 序列化的代码移至单独的程序集
  • 对于这个程序集:
  • 从扩展包中添加对上述程序集的Project 引用
  • 添加一个Browse.. 对扩展包中构建的序列化程序集的引用

【讨论】:

  • 这段代码运行良好(加上+".dll") - 非常感谢!我有一个问题:您为什么说“如果您已经构建和部署了 signed 序列化程序集”- 对程序集进行签名会有所不同吗?这一切似乎都没有......
  • 已经编辑了那个错误:)。使用 VS 15,当 SGEN 程序集未签名时,我得到“需要强命名程序集”。构建过程可能会自动为您签署 SGEN 程序集。
  • 我目前正在通过手动运行 sgen 来生成程序集,因此没有进行显式签名。不用担心——无论如何我都可以签名,以防万一。 (如果您不介意,“需要强命名程序集”错误是如何出现的?Assembly.LoadFrom() 的异常或其他异常?)
  • 我有一个 AppDomain.FirstChanceException 的处理程序(用于捕获 SGEN 程序集的失败加载),它观察到异常 AssemblyResolve 处理程序成功加载 SGEN 程序集之后。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-14
  • 1970-01-01
  • 2018-03-30
  • 2011-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多