如何为 DLL 而不是 EXE 选择 sgen 生成的 XmlSerializer DLL?

How to pick up an sgen-generated XmlSerializer DLL for a DLL rather than an EXE?

我有一个名为 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 的较新版本,有一个扩展只是程序文件中那些主要组件的加载器。该扩展使用 LoadFrom 加载这些主要组件,其中之一是 EntrianSourceSearch_14.dll.

如果您已经构建并部署了签名的序列化程序集,则可以在加载和缓存序列化程序时添加 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序列化的代码移动到单独的程序集
  • 对于这个程序集:
    • 签名
    • 启用 Build->Generate serialization assembly 选项
    • 应用workaround that makes the above option option actually work
    • 建造它
  • 从扩展包中添加对上述程序集的Project引用
  • 添加一个Browse..对扩展包中构建的序列化程序集的引用