Newtonsoft.Json发布具有相同强名称的不兼容版本,仅更改文件版本.
根据MSDN:
具有相同强名称的程序集应该相同.
因此,如果我们无法控制的其他应用程序将不同版本的Newtonsoft.Json.dll放入GAC,我们的应用程序就会中断.
有没有办法强制.NET加载我们需要的特定版本?
更新:
让我更深入地解释这个问题:
在.NET中,据我所知,在CLR尝试解决它们并失败之前,没有机制来解析程序集.
只有AppDomain.AssemblyResolve事件,它仅在未解析程序集时触发.通常它就足够了.
但是在Newtonsoft.Json的情况下,它并没有解决程序集,但它只是加载错误的程序集.
发生这种情况是因为Newtonsoft.Json发布了具有相同强名称的不兼容版本.
例:
假设我们的应用程序针对NJdll编译(程序集版本1.0,文件版本1.0)
然后一些其他应用程序,将其他不兼容版本的相同dll放入GAC NJdll(程序集版本1.0,文件版本1.1)
因为它们只更改文件版本而不更改程序集版本,所以这两个程序集具有相同的强名称.
因此,对于我们的应用程序.NET尝试解析NJdll(程序集版本1.0),它会在GAC中看到dll并加载它.(因为.NET总是喜欢从GAC组装来装配"bin"文件夹)
但装载的装配是错误的.它的文件版本为1.1,与1.0版本不兼容.
因为两个程序集都具有相同的程序集版本,所以.NET看不到它们之间的任何差异.但是当它实际上尝试解决内部的某个类或成员时,它会失败,因为它在版本1.1中已更改.
并且整个应用程序因不可预测的错误而失败.
最糟糕的是,即使我的应用程序没有将newtonsoft.json.dll放入GAC,我控制之外的其他一些应用程序也会将不同版本的newtonsoft.json.dll放入GAC - 我的应用程序会因不可预测而中断例外.
所以我的问题是,在.NET加载错误之前,我可以首先加载正确的程序集吗?
更新
https://github.com/JamesNK/Newtonsoft.Json/issues/615 https://github.com/JamesNK/Newtonsoft.Json/issues/1001
这个问题的问题已经结束,评论显示Newtonsoft.Json的作者不了解.NET版本以及为什么这很重要.
.net versioning json.net global-assembly-cache .net-assembly
如果程序集在本地计算机上的GAC(全局程序集缓存)中注册,那么以编程方式检查的最简单方法是什么?是否有一些易于使用的.NET API,我可以给它一个程序集DLL或Assembly对象本身的位置,以检查它是否存在于本地机器上的GAC中?在我的情况下,我正在检查的程序集已经被加载到程序检查的当前AppDomain中,因此我不确定调用Assembly.ReflectionOnlyLoad
和捕获异常将像我在其他帖子中看到的那样工作,加上这似乎有点hacky .
理想情况下,我想避免调用外部可执行文件gacutil.exe
来检查.
我为这种行为提出了一个连接问题.
VS 2015
复制到输出GAC
项目引用的引用,而不管复制本地设置如何.
VS 2010
不会使用相同的解决方案和项目,尊重复制本地属性.到目前为止,我发现的唯一解决方法是Microsoft.Web.Services3.dll
在项目A中添加一个直接引用,并将其设置为复制local = false.
重现步骤:
Project A
|__ Project B (Project Reference, copy local = true)
|__Microsoft.Web.Services3.dll (GAC, copy local = false)
Run Code Online (Sandbox Code Playgroud)
实际:
Microsoft.Web.Services3.dll
正被复制到项目A的输出目录中.
预期:
Microsoft.Web.Services3.dll
没有被复制到项目A的输出目录.
知道为什么会这样吗?在MSDN文档中明确指出GAC
的依赖不应该被复制到输出和VS 2010
尊重这一点.
我需要创建一个小应用程序或脚本来将.NET程序集安装到GAC中.我读过有几种方法可以做到这一点,包括:
gacutil.exe
执行以下代码行:
new System.EnterpriseServices.Internal.Publish().GACInstall("Foo.dll");
但是,如果我刚刚在机器上创建了相应的目录并将程序集复制到该目录中会发生什么?GAC目录的结构如下: C:\Windows\assembly\GAC_MSIL\Foo\<version#>__<public token>\Foo.dll
除了创建文件夹结构并将组件放入其中之外,上述两种方法是否有任何特殊之处?
我用C#创建了一个窗口应用程序.我正在发布成功的应用程序.
我看到了一些关于设置项目的解决方案,该解决方案自动与下面相同
我不想把这些dll放在GAC中.
对此有任何建议或解决方案.
我已经浏览了以下网址
错误消息"无法安装或运行应用程序.应用程序需要在GAC中使用stole Version 7.0.3300.0"
无法安装或运行应用程序:单击一次
c# publishing global-assembly-cache winforms visual-studio-2013
我正在使用Windows 7 Ultimate,尝试手动将文件复制到GAC中.我尝试使用Windows资源管理器,但它立即告诉我"访问被拒绝".我尝试使用具有提升权限的命令行,它说文件已被复制但我无法在任何地方找到程序集.
我正在更新第三方电子表格组件(GemBox),更新过程涉及手动将新版本的程序集删除到开发机器的GAC中.有什么建议?
是否有任何GUI可以在全局程序集缓存中查看,添加,删除程序集?
我有一个项目需要使用NHibernate与我的Oracle数据库进行通信.
我工作场所的许多项目都使用NHibernate,因此NHibernate程序集被放置在全局程序集缓存中,这是一个我不太了解的工具.根据我的研究,我收集了以下内容:
第二点显然与其他三个相矛盾,但如果它完全是假的,我就不会有任何引用库的问题.它肯定反映了现实,因为我的GAC程序集无法在"添加引用"窗口中找到.
我想知道两件事:
我有一个在Visual Studio 2005中开发的应用程序,我使用ClickOnce进行部署.我的解决方案包含两个项目 - 用VB编码的用户界面层和用C#编码的类库.我的C#类库有一些使用Outlook和Excel互操作程序集的代码(Microsoft.Office.Interop.Outlook和Microsoft.Office.Interop.Excel,版本11).这是我的问题.
如果(1. =是)那么
您将如何处理您的应用程序仅使用Interop程序集的几种功能的情况,这些功能将仅由少数总用户群使用?如果只有部分用户需要使用这些功能,为什么我必须要求我的应用程序的每个用户安装Microsoft Office?这些Interop程序集只是.dll文件,所以是什么使它们与其他文件不同,因为你不能只用你的项目发布文件,并且无论客户端安装了什么软件,都能满足引用?(显然,我对GAC的理解很差,并且它对Visual Studio的行为有影响.)我很乐意编写自己的代码来检查是否存在使用它们的少数功能所需的Office软件.没有办公室,无法访问功能......
其他
如果我对此的理解不正确,那么我如何设置我的引用和ClickOnce设置,以便用户在安装尝试时不会遇到以下错误?
"无法安装或运行应用程序.应用程序要求首先在全局程序集缓存(GAC)中安装程序集团版本11.0.0.0.
请联系您的系统管理员."
万一
我想我需要知道的主要事情是如何/如果我可以在我的出版物中包含这些程序集并满足或绕过GAC要求.
如果可能,请尽量直接回答我的具体问题.虽然文章很有帮助,但我已经阅读了很多文章并尝试了很多建议的解决方案并且没有找到成功.请记住,我对这一切的工作原理缺乏了解.
请原谅我缺乏理解,并感谢您提供的任何帮助.非常感谢!
excel outlook interop visual-studio-2005 global-assembly-cache
我想在使用Visual Studio编译应用程序时可靠地在GAC中自动安装我的应用程序集.我在我的Web应用程序的构建中设置了构建前和构建后事件.
预建活动:
"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\gacutil.exe" /f /ul Uninstall.Gac.txt
Run Code Online (Sandbox Code Playgroud)
发布后事件:
"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\gacutil.exe" /f /il Install.Gac.txt
%windir%\system32\inetsrv\appcmd.exe recycle apppool -apppool.name:"Sharepoint IIS WebApps"
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我还在回收我的Web应用程序池,以便新程序集开始工作.
我遇到的问题是这是一个非常不可靠的过程.如果我的Web应用程序失败,我的下一个版本将失败,因为卸载将失败(后期构建未在以前的版本上运行)...等等.
我想尽可能让这个过程变得可靠.我想条件卸载和组装,如果它们存在并强行安装,无论它们是否存在......但是预构建事件对于下一个原因仍然很重要:
在构建之前完全卸载所有程序集是很重要的,否则它们不会被复制到我的输出目录(因为编译器在GAC中找到它们),因此GAC安装失败,因为它无法在output\bin文件夹中找到程序集.
我应该如何在我的Web应用程序构建中可靠地执行GAC卸载和安装?
gacutil visual-studio-2010 global-assembly-cache build-events
.net ×6
c# ×3
assemblies ×1
build-events ×1
copy-local ×1
excel ×1
gac ×1
gacutil ×1
install ×1
interop ×1
json.net ×1
outlook ×1
publishing ×1
versioning ×1
windows-7 ×1
winforms ×1