.net Windows 服务中绑定重定向的 SideBySide 错误 [英] SideBySide Error with Binding Redirect in .net Windows Service

查看:21
本文介绍了.net Windows 服务中绑定重定向的 SideBySide 错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 .net Windows 服务,它需要加载两个不同版本的程序集.它在 server 2012 R2 机器上运行.我在单独的 .config 文件中使用绑定重定向,该文件在关闭 </configuration> 节点(参见 MSDN 文档):

<linkedConfiguration href="file://E:\my-service\runtime.config"/></assemblyBinding>

我的 runtime.config 包含实际的绑定重定向:

<预><代码><配置><运行时><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><依赖程序集><assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005"culture="neutral"/><codeBase version="0.4.0.126" href="AutoMapper.dll"/></dependentAssembly><依赖程序集><assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005"culture="neutral"/><codeBase version="3.2.1.0" href="AutoMapper.3.2.1\AutoMapper.dll"/></dependentAssembly></assemblyBinding></运行时></配置>

这可以正常工作,直到服务器重新启动.然后我们在机器启动后的事件日志中看到这一点:

Service.exe"的激活上下文生成失败.第 71 行的清单或策略文件Service.exe.Config"中出现错误.元素 assemblyBinding 显示为此版本的 Windows 不支持的元素配置的子项.

所以我运行了 sxstrace.exe 工具(根据这个 blog) 并获得此输出:

==================开始激活上下文生成.输入参数:标志 = 0处理器架构 = AMD64CultureFallBacks = en-US;en清单路径 = E:\my-service\Service.exeAssemblyDirectory = E:\my-service\应用程序配置文件 = E:\my-service\Service.exe.Config-----------------信息:解析应用程序配置文件 E:\my-service\Service.exe.Config.错误:第 71 行:元素 assemblyBinding 显示为此版本的 Windows 不支持的元素配置的子项.错误:激活上下文生成失败.结束激活上下文生成.

如果我从主 app.config 中删除 linkedConfiguration,服务将启动(尽管有不同的错误).然后我可以重新添加它,并且可以正常启动和停止服务,直到机器再次重新启动.

有谁知道为什么会发生这种情况?这是 linkedConfiguration 的正确用法吗?

更新

在与 Microsoft 支持人员进行了长时间且富有成效的对话后,我发现不支持将 linkedConfiguration 与嵌入式清单一起使用 (参见 MSDN 文档).

但是,从外部文件加载配置似乎存在错误.我已将此作为 连接错误.

解决方案

遵循 Microsoft 支持的更新和 @cmckeegan,我们将绑定重定向的外部配置文件移开,而是将其移至代码中.我们现在在我们的 组合根中调用 BindingRedirects.Register().

BindingRedirects 类如下所示:

公共静态类BindingRedirects{静态只读字典<字符串,字符串>重定向 = 新字典<字符串,字符串>{{ "AutoMapper, Version=3.2.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005", @"AutoMapper.3.2.1\AutoMapper.dll"}};公共静态无效寄存器(){AppDomain.CurrentDomain.AssemblyResolve += (o, args) =>{if (Redirects.ContainsKey(args.Name)){var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Redirects[args.Name]);返回 Assembly.LoadFrom(path);}返回空;};}}

I have a .net windows service which needs to load two different versions of an assembly. It runs on a server 2012 R2 box. I am using a binding redirect in separate .config file which is loaded into the main app.config using this before the closing </configuration> node (see MSDN doc):

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
  <linkedConfiguration href="file://E:\my-service\runtime.config" />
</assemblyBinding>

My runtime.config contains the actual binding redirect:

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
        <codeBase version="0.4.0.126" href="AutoMapper.dll" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
        <codeBase version="3.2.1.0" href="AutoMapper.3.2.1\AutoMapper.dll" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>  
</configuration>

This works fine until the server is rebooted. We then see this in the event log after the machine starts:

Activation context generation failed for "Service.exe".
Error in manifest or policy file "Service.exe.Config" on line 71. 
The element assemblyBinding appears as a child of element configuration which is not supported by this version of Windows.

So I ran the sxstrace.exe tool (as per this blog) and get this output:

=================
Begin Activation Context Generation.
Input Parameter:
    Flags = 0
    ProcessorArchitecture = AMD64
    CultureFallBacks = en-US;en
    ManifestPath = E:\my-service\Service.exe
    AssemblyDirectory = E:\my-service\
    Application Config File = E:\my-service\Service.exe.Config
-----------------
INFO: Parsing Application Config File E:\my-service\Service.exe.Config.
    ERROR: Line 71: The element assemblyBinding appears as a child of element configuration which is not supported by this version of Windows.
ERROR: Activation Context generation failed.
End Activation Context Generation.

If I remove the linkedConfiguration from the main app.config the service starts (albeit with different errors). I can then add it back in and the service can be started and stopped fine until the machine is rebooted again.

Does anyone know why this would happen? And is this the correct use of the linkedConfiguration?

UPDATE

After and long and productive conversation with Microsoft support, I discovered that using the linkedConfiguration with an embedded manifest is not supported (see MSDN doc).

However there does appear to be a bug with loading the config from an external file. I have raised this as a bug on connect.

解决方案

Following the update from Microsoft support and a suggestion from @cmckeegan, we moved away from an external config file for our binding redirect and moved it into code instead. We now call BindingRedirects.Register() in our composition root.

The BindingRedirects class looks like this:

public static class BindingRedirects
{
    static readonly Dictionary<string, string> Redirects = new Dictionary<string, string>
    {
        { "AutoMapper, Version=3.2.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005", @"AutoMapper.3.2.1\AutoMapper.dll"}    
    }; 

    public static void Register()
    {
        AppDomain.CurrentDomain.AssemblyResolve += (o, args) =>
        {
            if (Redirects.ContainsKey(args.Name))
            {
                var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Redirects[args.Name]);
                return Assembly.LoadFrom(path);
            }

            return null;
        }; 
    }
}

这篇关于.net Windows 服务中绑定重定向的 SideBySide 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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