无法在COM可见的类库C#中加载文件或程序集 [英] Could not load file or assembly in COM visible class library C#

查看:44
本文介绍了无法在COM可见的类库C#中加载文件或程序集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了一个类库项目,并安装了Newtonsoft.Json NuGet软件包.此操作添加了一个app.config文件,该文件包含:

I've created a class library project, and installed Newtonsoft.Json NuGet package. This operation added an app.config file, which contains:

<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
  <dependentAssembly>
    <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
  </dependentAssembly>
</assemblyBinding>

然后我使类库COM可见:

Then I've made the class library COM visible:

当我尝试在另一个C#WinForms项目中使用我的类库时,出现错误:

When I tried to use my class library in another C# WinForms project, I was getting error:

System.IO.FileLoadException:无法加载文件或程序集"Newtonsoft.Json,版本= 4.5.0.0,文化=中性,PublicKeyToken = 30ad4fe6b2a6aeed"或其依赖项之一.找到的程序集的清单定义与程序集引用不匹配.(来自HRESULT的异常:0x80131040)

System.IO.FileLoadException : Could not load file or assembly 'Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

直到我在WinForms项目中添加了相同的app.config行.

until I've added the same app.config lines in the WinForms project.

现在,我正在尝试在Microsoft Word VBA开发人员中使用我的程序集(通过COM引用),并且遇到相同的错误,但是我无法为Microsoft Word创建app.config文件,可以吗?有什么办法可以解决这个问题?

Now I'm trying to use my assembly (referenced via COM) in Microsoft Word VBA developer, and I'm getting the same error, but I can't make an app.config file for Microsoft Word, can I? Is there any way, how this issue can be solved?

提前谢谢!

推荐答案

是的,当您制作.NET程序集时,这是一个标准的DLL Hell问题[ComVisible].CLR使用其常规方法来查找相关程序集,而这些规则在COM中不会更改.它首先在GAC中查找,然后在EXE所在的目录中查找.它不会在[ComVisible]程序集所在的目录中查找.否则,一定要使用Fuslogvw.exe轻松看到它.

Yes, this is a standard DLL Hell problem you'll have when you make a .NET assembly [ComVisible]. The CLR uses its normal way to look for dependent assemblies, those rules do not change in COM. It first looks in the GAC, it next looks in directory where the EXE is located. It does not look in the directory where your [ComVisible] assembly is located. Otherwise something that is easy to see with Fuslogvw.exe, be sure to practice it.

有多种解决方案,都不是理想的解决方案,因此您必须选择最适合自己的解决方案.您应该强烈要做的第一件事是摆脱.config文件.< bindingRedirect> 始终会生成,但通常是不必要的.仅当您引用多个Nuget程序包并且它们对于要使用哪个版本的Newtonsoft.Json.dll不相同时,才真正需要它.如果这是一个问题,那么只有将其部署到Office文件夹中才是可行的,请参阅最后一个项目符号.

There are multiple solutions to this problem, none are ideal so you'll have to pick the one that suits you best yourself. First thing you should strongly pursue is to get rid of the .config file. The <bindingRedirect> is always generated but is often unnecessary. It is only truly required when you reference multiple Nuget packages and they disagree about what version of Newtonsoft.Json.dll to use. If that's a problem then only deployment into the Office folder is practical, see the last bullet.

  • 将所有内容部署到GAC.这通常是COM的理想解决方案,由于注册是在整个计算机范围内进行的,因此通常会遇到严重的DLL Hell问题.这使得部署更新很危险,您可能在一个程序中解决了一个问题,但又破坏了另一个程序.缺点是安装要求.将Newtonsoft.Json.dll放入GAC中的做法值得商question,GAC是一种具有非常不透明的版本控制历史记录并被许多其他程序使用的程序集.非零赔率会破坏使用它的另一个应用程序,因为它现在将副本加载到GAC中,而不是其本地副本中.FUD的强度足以避免这种情况.

  • Deploy everything to the GAC. This is normally the ideal solution for COM, it has a strong DLL Hell problem in general because registration is machine-wide. That makes deploying updates dangerous, you might fix a problem in one program but break another. Disadvantage is the install requirement. And the questionable practice of putting Newtonsoft.Json.dll in the GAC, an assembly that has a pretty opaque versioning history and is used by many other programs. Nonzero odds you'll break another app that uses it since it now loads the copy in the GAC instead of its local copy. The FUD is strong enough to avoid this.

使用ILMerge,因此您只有一个DLL.并不总是有效,它不能处理混合模式程序集,也不能处理绑定重定向.试试看,您会很快发现.除此之外,唯一的缺点是额外的构建步骤.

Use ILMerge so you'll only have a single DLL. Does not always work, it can't handle mixed-mode assemblies and cannot handle binding redirects. Try it and you'll quickly find out. Other than that, the only disadvantage is the extra build step.

订阅AppDomain.CurrentDomain.AssemblyResolve事件,并帮助CLR查找依赖关系.当您公开有限数量的类或只有少数具有依赖项时,此方法很实用.最好在类的静态构造函数中订阅事件,以便尽早发生.确保只做一次.一定要在没有调试器的情况下测试发布版本,抖动可能需要依赖项才能开始运行任何代码.

Subscribe the AppDomain.CurrentDomain.AssemblyResolve event and help the CLR to locate the dependency. Practical when you expose a limited number of classes or if only a few have a dependency. Best to subscribe the event in the static constructor of the class so it happens as early as possible. Be sure to do it only once. Be sure to test the Release build without a debugger, the jitter might require the dependency before any code starts running.

将依赖项复制到Office安装文件夹中.这就是CLR在检查GAC之后将要处理的地方.如果您需要bindingRedirect,则还需要将配置文件也复制到那里,重命名为Excel.exe.config以与Office程序名称匹配.缺点是管理员不喜欢您弄乱该文件夹.还有两个程序执行此操作的问题,第二个可能是在您完成项目数年后覆盖DLL或.config文件.这不是您的问题,无论如何您都会收到一个丑陋的电话.

Copy the dependencies into the Office install folder. That's where the CLR will look after it checked the GAC. If you need the bindingRedirect then the config file needs to be copied there as well, renamed to, say, Excel.exe.config to match the Office program name. Disadvantage is an admin that doesn't like you messing with that folder. And the problem of two programs doing this, the second overwriting your DLL or .config file, perhaps years after you finished your project. Not your problem, you'll get an ugly phone call anyway.

这篇关于无法在COM可见的类库C#中加载文件或程序集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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