如何找出哪个应用程序需要GAC的某个程序集?

时间:2015-12-10 00:21:02

标签: .net dll windows-installer gac

我继承了一个使用Microsoft Enterprise Library的应用程序。应用程序的VS解决方案包含大约200个项目。

我一直在重组解决方案,移动项目并删除过时的项目。我需要整理它以便为其他开发人员做好准备。

该解决方案包含特定版本的Microsoft Enterprise Library dll,但是当我移动内容时,我注意到有些项目没有引用这些dll,而是来自我的GAC。

我需要确保解决方案要么不依赖于安装的任何其他内容(在GAC或其他方面),要么确保文件是否存在,因此当从源代码控制中提取时,下一个人不会有令人讨厌的意外。

我尝试从GAC中删除Enterprise Library dll。这是失败的:

C:\WINDOWS\system32>gacutil /u Microsoft.Practices.EnterpriseLibrary.Common
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.


Assembly: Microsoft.Practices.EnterpriseLibrary.Common, Version=4.1.0.0, Culture=neutral, PublicKeyToken=e44a2bc38ed2c13c, processorArchitecture=MSIL
Unable to uninstall: assembly is required by one or more applications
Pending references:
              SCHEME: <WINDOWS_INSTALLER>  ID: <MSI>  DESCRIPTION : <Windows Installer>
Number of assemblies uninstalled = 0
Number of failures = 0

这条消息让我觉得这个dll是由安装了Windows Installer(MSI)的应用程序引用的。

我的计算机没有Microsoft Enterprise Library作为“控制面板/程序和功能”中的项目之一。

如何找出在gac中安装了哪些安装了MSI的产品?

编辑:不是骗局。另一个问题询问过程浏览器未在GAC中显示程序集时的情况,并且KB正在讨论当程序集未被任何内容引用时无法删除程序集的情况。另一个问题的进程资源管理器部分与我无关,因为我不希望程序集一直被加载。 kb响应也没有帮助,因为我不想删除程序集我想找出安装它的程序。其他问题的答案没有回答(因为那不是那里的问题),但幸运的是我得到了质量答案这里

3 个答案:

答案 0 :(得分:2)

对我来说总是有用的快捷方式是打开cmd提示符,转到c:\ windows \ installer并执行一个findtr:

findstr / s -i -m AssemblyName.dll * .msi

如果您发现任何匹配,您将获得一个或多个短散列名称以.msi结尾的文件。使用Windows Installer数据库编辑器&#34; ORCA&#34; (安装平台SDK或谷歌ORCA.msi)检查这些数据库中的每一个,并查看哪些数据库具有将所述文件安装到GlobalAssemblyCache目录的组件。如果MsiAssembly表中存在程序集,并且File_Application字段为空,则将其安装到GAC。 找到后,查看属性表和摘要信息流(顶部菜单 - &gt;查看 - &gt;摘要信息),以确定缓存的MSI所代表的产品。

答案 1 :(得分:2)

我使用脚本来枚举系统上的所有组件,它们的guids,安装它们的位置以及拥有的产品代码和名称。运行可能需要一段时间。

Option Explicit
Public installer, fullmsg, comp, a, prod, fso, pname, ploc, pid, psorce

Set fso = CreateObject("Scripting.FileSystemObject")
Set a = fso.CreateTextFile("comps.txt", True)

' Connect to Windows Installer object
Set installer = CreateObject("WindowsInstaller.Installer")
a.writeline ("MSI Components")
on error resume next
For Each comp In installer.components
   a.writeline (comp & " is used by the product:")
   for each prod in Installer.ComponentClients (comp) 
      pid = installer.componentpath (prod, comp) 
      pname = installer.productinfo (prod, "InstalledProductName")
      a.Writeline ("     " & pname & " " & prod & "and is installed at " & pid)
   Next
Next

答案 2 :(得分:0)

这里有很多东西需要理解。首先,GAC将成为获取程序集的首选位置。因此,在您的开发机器上从GAC中删除EL组件。将Nuget包中的EL添加到项目中。可以在那里手动添加GAC中的程序集。不一定使用MSI。如果您希望项目忽略其他版本,例如GAC中的版本。在项目的参考文献中,选择有问题的参考文献并设置&#34;特定版本&#34;到true。现在,如果版本不匹配,您的项目将不再用GAC中的原始参考替换原始参考。此时,您可以将该版本的EL添加到bin中,或者您拥有的任何内容。

对于这样大的解决方案,我的建议是创建以下结构

- Solution
  - packages(nuget)
  - bin
  - Project 1
  - . . . .  .
  - Project N
  • 删除所有项目引用,并将其替换为bin中对dll的引用。
  • 设置项目以将输出构建为bin
  • 创建构建订单。
  • 从GAC中删除任何dll,从GAC中删除任何第三方dll并放入bin。只有以&#34;系统&#34;开头的dll;可以在GAC或&#34;项目文件&#34;等packagesbin中应该有其他任何其他内容。 (虽然在某些情况下从packages抓取并移至bin
  • 会很有用
  • 在您的项目参考中,将任何非系统dll设置为copy local = true,通常/通常都应该specific version = false

一旦你做了这些项目,生活对你来说将是件好事。