zoukankan      html  css  js  c++  java
  • 将DLL程序集加入GAC后的一系列问题汇总,及解决方法

    历史背景:

      公司有10来个团队项目,每个项目下又有1-4个Site或Service,还有一些Winform、Windows Scheduler等,这样算下来会有近30个项目及相关多个DLL项目,每个项目都可能会用到一些公共的DLL,像:Enterprise Library、NPOI、OpenXML、AspNetPager、Newtonsoft.Json、AppFabric、PanGu等,而这些公共的有些会被再封装,最后项目里可能会引用一个封装过DLL或原DLL,一般DLL间如果有依赖,只要这几个DLL在一起,引用一个封装后的,其它DLL会一并在生成时放入bin下,但有些DLL依赖比较弱(如反射)、或是使用别的什么高深的做法做到没有直接依赖关系、或者Copy DLL时没有将其依赖DLL也一并Copy过来,反正最后是需要那个DLL、但程序却找不着,导致运行时错误。项目一大,这样的错就太难找了,除非做好足够的测试程序,去自动检测。

     解决思路:

      针对以上问题,我们使用TFS管理,每个团队项目都会有一个放DLL的公共区,供这个团队项目下的所有项目引用。如果公用或相关DLL有更新都需要更新各个团队项目下的DLL公共区。但有时因为忙或其它原因,没有及时更新,过后又忘了,而其他人又不知道。这样的问题出现的多了,有些人干脆直接引用所有公共DLL,但这样一来,每次重新生成、发布、打包都得为复制DLL付出时间成本,很不方便。问题反反复复,一次次为此所累后,我受不了了!!!最近不太忙,同事又遇到这样的问题,实在不想搞了,技术高有耐心的调试跟踪一把也能解决。

      但我的观点很简单:如果什么都不做就能解决问题,那就什么都不要做!!! 于是下定决心:不能再让这样的事发生在我身上,也不能让他发生在我们组员身上,因为这样做会让他们把太多的精力花在这些不仅不能产生效益,反而严重影响开发进度的事情上,并且是持续的折磨开发人员,有时会让人产生放弃这个工作的念头。

     解决方案:

       就在有这个想法的一刹那,我想想到了.net Framework,他不就是将公共的DLL全都注册到GAC里,DLL之间的相互依赖也都是从GAC里找,并且相关DLL不在项目里引用时也照样正常工作,非要引用时VS也会出错提示。如果把我们公共DLL都装到GAC,那这一系列问题不都搞定了?Good!!!

      经过一番研究,终于将这些DLL都注册到GAC了,本以为像.net Framework一样,正常工作。但事实并不是这样,首先注册后在VS里的“添加引用”里找不到,得自己定位到DLL目录,那个郁闷呀,.net Framework可以放进去,我这个肯定也能!网上转了一圈,找到方案:除了将DLL注册到GAC后,还需要再将DLL复制到一个目录,并在注册表里为VS做下指引。做完这些后,感觉没问题了,用了一天时间把所有项目的引用都改到GAC引用后,执行TFS里的生成(我们的生成里带了发布的代码),一切OK,看着过往生成记录,现在生成及发布比以前的时间缩短了,兴奋呀。但一测试发现,很多页面都有问题,分析后发现是企业库问题。这时已经影响到别的项目开发了,所又抱怨声很多,甚至之前支持我这个想法的同事也不经意的说起:还是引用本地DLL吧,但他们可曾知道我为了解决这个问题忍受了多久、眼看就要成功了怎么就能这么轻易放弃?同事帮我调了一把实在也搞不明白,下班很久了,都累了,他们也先回去了,但这问题不解决明天还一样影响到别人工作,我决不会这么做的。不吃饭,继续研究,发现确实是EntLib问题,研究过程中同事在回家车上发来短信给了一文章,看了后发现还真可以解决,应用到一个项目上测试没问题后再次发布所有项目。大致走了一遍,ALL OK。爽。

      这次问题解决时间较长,所以产生了写此文章的想法,记录下自己的心路历程,为又后失意时打气。耳边响起了以前常听的一首歌曲《梦想旅程》 :  

    人生就像走这一条属于我们自己的路
    未知前方有着多少崎岖有着多少迷雾
    只要自己坚定信念决不放弃自己的梦
    哪怕前方的路有多苦
    不管自己理想梦想是否能实现
    我对自己说我决不放弃决不认输
    属于我们未来就在我们的手中
    为了自己梦想人生的路  

    最后给出遇到的问题及解决方案:

    企业库加入GAC后:Data Access与Validation无法正常工作,可以通过以下配置解决:

    <configSections>
    <section name="typeRegistrationProvidersConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.TypeRegistrationProvidersConfigurationSection, Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    </configSections>

    <typeRegistrationProvidersConfiguration>
    <remove name="Data Access"/>
    <add name="Data Access" providerType="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSyntheticConfigSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

    <remove name="Validation"/>
    <add name="Validation" providerType="Microsoft.Practices.EnterpriseLibrary.Validation.Configuration.ValidationTypeRegistrationProvider, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    </typeRegistrationProvidersConfiguration>

    参考地址:http://entlib.codeplex.com/workitem/26903

    其它组件加入GAC后网站仍找不到程序集,需要在配置文件里再次声明,如:

    <system.web>
    <compilation debug="true" targetFramework="4.0">
    <assemblies>
    <add assembly="AspNetPager, Version=7.3.2.0, Culture=neutral, PublicKeyToken=fb0a0fe055d40fd4, processorArchitecture=MSIL"/>
    <add assembly="Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
    <add assembly="Microsoft.ReportViewer.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
    <add assembly="Microsoft.Build.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
    <add assembly="System.Management, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
    </assemblies>
    </compilation>
    </system.web>

    以上两个情况也都可以通过以下方式实现:

    <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Caching" fullName="Microsoft.Practices.EnterpriseLibrary.Caching, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Caching.Cryptography" fullName="Microsoft.Practices.EnterpriseLibrary.Caching.Cryptography, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Caching.Database" fullName="Microsoft.Practices.EnterpriseLibrary.Caching.Database, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Common" fullName="Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Configuration.Design.HostAdapter" fullName="Microsoft.Practices.EnterpriseLibrary.Configuration.Design.HostAdapter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Configuration.Design.HostAdapterV5" fullName="Microsoft.Practices.EnterpriseLibrary.Configuration.Design.HostAdapterV5, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Configuration.DesignTime" fullName="Microsoft.Practices.EnterpriseLibrary.Configuration.DesignTime, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Configuration.EnvironmentalOverrides" fullName="Microsoft.Practices.EnterpriseLibrary.Configuration.EnvironmentalOverrides, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Data" fullName="Microsoft.Practices.EnterpriseLibrary.Data, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Data.SqlCe" fullName="Microsoft.Practices.EnterpriseLibrary.Data.SqlCe, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling" fullName="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging" fullName="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF" fullName="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Logging" fullName="Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Logging.Database" fullName="Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.PolicyInjection" fullName="Microsoft.Practices.EnterpriseLibrary.PolicyInjection, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Security" fullName="Microsoft.Practices.EnterpriseLibrary.Security, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Security.AzMan" fullName="Microsoft.Practices.EnterpriseLibrary.Security.AzMan, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Security.Cache.CachingStore" fullName="Microsoft.Practices.EnterpriseLibrary.Security.Cache.CachingStore, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Security.Cryptography" fullName="Microsoft.Practices.EnterpriseLibrary.Security.Cryptography, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Validation" fullName="Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Validation.Integration.AspNet" fullName="Microsoft.Practices.EnterpriseLibrary.Validation.Integration.AspNet, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF" fullName="Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WinForms" fullName="Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WinForms, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WPF" fullName="Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WPF, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.ServiceLocation" fullName="Microsoft.Practices.ServiceLocation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.Unity" fullName="Microsoft.Practices.Unity, Version=2.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.Unity.Configuration" fullName="Microsoft.Practices.Unity.Configuration, Version=2.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.Unity.Interception" fullName="Microsoft.Practices.Unity.Interception, Version=2.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <qualifyAssembly partialName="Microsoft.Practices.Unity.Interception.Configuration" fullName="Microsoft.Practices.Unity.Interception.Configuration, Version=2.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    </assemblyBinding>
    </runtime>

    注册到GAC后,在VS的添加引用里看不到、及DLL的注释没了,解决方法是:

    将这些DLL及相应的XML说明文档再放到一个位置,然后在注册表添加指引来解决。

    如:目前都放在:C:\WINDOWS\Common.Reference.Assemblies\,按目录分隔各功能,

    注册表里写法如下,每一个都会定位到对应的功能目录(只有一级目录的DLL会显示在VS的添加引用里):

    Windows Registry Editor Version 5.00

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx\Common.Reference.Assemblies.AppFabric]
    @="C:\\WINDOWS\\Common.Reference.Assemblies\\AppFabric"

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx\Common.Reference.Assemblies.AspNetPager]
    @="C:\\WINDOWS\\Common.Reference.Assemblies\\AspNetPager"

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx\Common.Reference.Assemblies.EntLib]
    @="C:\\WINDOWS\\Common.Reference.Assemblies\\EntLib"

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx\Common.Reference.Assemblies.Json]
    @="C:\\WINDOWS\\Common.Reference.Assemblies\\Json"

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx\Common.Reference.Assemblies.NPOI]
    @="C:\\WINDOWS\\Common.Reference.Assemblies\\Office"

    首发地址:.net环境,将DLL程序集加入GAC后的一系列问题汇总 http://www.yongfa365.com/Item/Custom-DLL-To-GAC.html

  • 相关阅读:
    【第40套模拟题】【noip2011_mayan】解题报告【map】【数论】【dfs】
    【模拟题(63550802...)】解题报告【贪心】【拓扑排序】【找规律】【树相关】
    【模拟题(电子科大MaxKU)】解题报告【树形问题】【矩阵乘法】【快速幂】【数论】
    IMemoryBufferReference and IMemoryBufferByteAccess
    SoftwareBitmap and BitmapEncoder in Windows.Graphics.Imaging Namespace
    Windows UPnP APIs
    编译Android技术总结
    Windows函数转发器
    Two Ways in Delphi to Get IP Address on Android
    Delphi Call getifaddrs and freeifaddrs on Android
  • 原文地址:https://www.cnblogs.com/dajiang02/p/2243997.html
Copyright © 2011-2022 走看看