【问题标题】:Making binding redirects work for office add-ins使绑定重定向适用于 Office 加载项
【发布时间】:2014-09-04 11:31:35
【问题描述】:

我在我的 Word 插件中使用 Microsoft.Bcl.Async,我的插件被编译为一个 exe (test_addin.exe) 文件,它作为一个程序集从 Microsoft Word 加载,当我直接启动可执行文件时,一切正常很好,但是当我从 Word 运行它时,我收到一条错误消息,提示它无法加载 Systems.Threading.Tasks 程序集。

Could not load file or assembly System.Threading.Tasks...

看起来它与绑定重定向有关,当我尝试从 Word 运行应用程序时,它希望配置文件位于 'C:\Program Files (x86)\Microsoft Office\Office15' 文件夹中并命名为 WINWORD.exe.config,不幸的是这是不可能的,因为我可能无权访问该文件夹。

我的 test_addin.exe.config 文件:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
    </startup>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.6.9.0" newVersion="2.6.9.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.6.9.0" newVersion="2.6.9.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

我已尝试将 AppDomain.CurrentDomain.SetupInformation.ConfigurationFile 设置为指向正确的路径,但似乎没有帮助,是否有其他方法可以使其适用于 Office 加载项?

【问题讨论】:

    标签: c# office-interop .net-assembly assembly-resolution


    【解决方案1】:

    我通过实现自定义 AssemblyResolve 处理程序解决了这个问题

        Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs e)
        {
            try
            {
                if (!e.Name.ToLower().StartsWith("system.threading.tasks"))
                    return null;
    
                AddoDebug.Instance.WriteLine("Assembly_Resolve");
                var assemblyDetail = e.Name.Split(',');
                var assemblyBasePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                var assembly = Assembly.LoadFrom(assemblyBasePath + @"\" + assemblyDetail[0] + ".dll");
    
                return assembly;
            }
            catch (Exception ex)
            {
                AddoDebug.Instance.WriteLine("An exception occurred: " + ex, ADDOTraceStatus.Exception);
                return null;
            }
        }
    

    但我不确定这是一个好的解决方案,所以我将这个问题留待新的答案。

    【讨论】:

    • 优先使用Assembly.Load而不是Assembly.LoadFromLoadFrom 不会对加载的程序集进行重复数据删除,并导致公共语言运行时认为程序集的多个实例是不同的程序集。
    【解决方案2】:

    Office 2016 和 365 从您的配置文件中读取绑定重定向。但是,如果您的插件需要在旧版 Office 上运行,AppDomain.AssemblyResolve 事件(如 @animaonline 所述)将允许实现自定义绑定重定向行为。

    下面的代码演示了一个解决方案,对于每个加载失败的程序集,它会尝试回退到从应用程序的基目录加载同名的程序集。如果应用程序目录中存在同名的程序集,则加载并返回该程序集。

    using System;
    using System.IO;
    using System.Reflection;
    
    public partial class ThisAddIn
    {
        static ThisAddIn()
        {
            // The event must be hooked as early as possible. That's why
            // we use the static constructor.
            AppDomain.CurrentDomain.AssemblyResolve += TryLoadFromBaseDirectory;
        }
    
        private static Assembly TryLoadFromBaseDirectory(object sender, ResolveEventArgs e)
        {
            // This event is called for any assembly that fails to resolve.
            var name = new AssemblyName(e.Name);
    
            var assemblyPath =
                Path.Combine(AppDomain.CurrentDomain.BaseDirectory, name.Name + ".dll");
    
            if (File.Exists(assemblyPath))
            {
                // If we find this missing assembly in the application's base directory,
                // we simply return it.
                return Assembly.Load(AssemblyName.GetAssemblyName(assemblyPath));
            }
            else
            {
                return null;
            }
        }
        ...
    }
    

    由于您随应用程序发布的程序集版本通常是您希望 .NET 运行时使用的版本,这似乎是一种强大的“包罗万象”机制。

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题,但是,在我的情况下,我的加载项是一个 DLL。强制 DLL 生成绑定重定向解决了它。编辑csproj 并添加以下内容:

      <PropertyGroup>
        <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
        <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
      </PropertyGroup>
      

      【讨论】:

        猜你喜欢
        • 2012-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-23
        • 1970-01-01
        • 2011-11-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多