如何从全局程序集缓存中提取程序集?

142

我必须处理一个将程序集直接安装到全局程序集缓存 (例如在%windows%/assembly深处) 的软件包。

我该如何将实际的程序集(DLL)从全局程序集缓存中移除,放到普通文件系统中?

谢谢。

15个回答

151

我使用了这篇文章中的建议从全局程序集缓存(GAC)中获取一个程序集。

将DLL从GAC中取出

一旦部署在GAC(通常位于c:\ windows \ assembly),DLL文件就无法像普通DLL文件那样查看或使用。它们不能直接从VS项目中引用。开发人员通常会在开发(设计)时保留原始DLL文件的副本,并在项目中引用该文件,而在项目运行时则使用来自GAC的程序集。

在执行(运行时)过程中,如果发现程序集已签名并部署在GAC中,则CLR会自动从GAC中选择程序集,而不是在VS设计时间中引用的DLL。如果开发人员删除了原始DLL,或由于某种原因没有它,则有一种方法可以从GAC获取DLL文件。按照以下步骤从GAC复制DLL:

  1. 运行regsvr32 /u C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\shfusion.dll

    • shfusion.dll是资源管理器扩展DLL,为GAC文件夹提供了独特的外观。取消注册此文件将删除程序集缓存查看器,GAC文件夹将像资源管理器中的任何普通文件夹一样可见。
  2. 打开“%windir%\assembly\GAC_MSIL”。

  3. 浏览到您的DLL文件夹,以深入查找您的DLL。

  4. 在硬盘上的某个地方复制DLL文件,并在项目中从那里引用它

  5. 运行命令 "regsvr32 %windir%\Microsoft.NET\Framework\<.NET版本目录>\shfusion.dll" 重新注册 shfusion.dll 文件,恢复 GAC 的原始独立视图。


82
这个方法可行但有些复杂。如果你不怕命令提示符,你可以直接进入所需目录并以此方式复制DLL。 - Cheeso
3
只需安装TotalCommander并启用查看所有隐藏文件选项,就可以获取您想要的每个程序集。 - Patrick Peters
4
@Andrew,看起来shfusion.dll不支持regsvr32通过/i选项调用的DllInstall()入口点。省略该选项可以成功重新注册组件。 - Frédéric Hamidi
9
您可以跳过步骤1和2,直接前往%windir%\assembly\GAC_MSIL,并从那里浏览。 - Christian Fredh
5
@ChristianFredh 提醒一下:对我来说,这只能直接从“运行”对话框中完成。 - xr280xr
显示剩余6条评论

109

99

打开命令提示符并键入:

cd  c:\windows\assembly\GAC_MSIL 

xcopy . C:\GacDump /s /y
这应该会给出整个GAC的转储。 祝你使用愉快!

11
迪帕克的回答更清晰,并使用了带有适当标志的xcopy。 - katbyte
我会把这个答案评为第一,因为在按照步骤逐步操作时遇到问题后,只用了5秒钟就解决了所有问题。 - FBryant87

27

是的。

添加DisableCacheViewer注册表项

在HKLM\Software\Microsoft\Fusion\下创建一个名为DisableCacheViewer的新DWORD键,并将其值设置为1。

返回Windows资源管理器中的程序集文件夹,就可以看到正常的文件系统视图了。


3
被低估的答案。谢谢! - xr280xr
1
这是真正的解决方案。易于撤销,无需命令行。 - user2920518

16

我认为最简单的方法是通过命令行来完成,就像David提到的那样。唯一的诀窍在于.dll文件并不仅仅位于C:\Windows\Assembly。你需要导航到C:\Windows\Assembly\GAC\[ASSEMBLY_NAME]\[VERSION_NUMBER]_[PUBLIC KEY]。然后可以使用以下命令进行复制:

copy [ASSEMBLY_NAME].dll c:\(或任何您想要的位置)

希望这能有所帮助。


14

打开RUN窗口,然后输入%windir%\assembly\GAC_MSIL ,这将以文件夹视图的方式打开您的dll文件,接着您可以浏览到您需要的dll文件所在的文件夹并打开它,您将会找到您的dll文件并轻松复制。


非常简单的解决方案。谢谢。 - Dblock247

13

我发现的简单方法是打开命令提示符并浏览你提到的文件夹,直到找到所需的DLL文件 - 然后可以使用复制命令将其导出。Windows资源管理器对该文件夹有一个“有用”的特殊视图。


今天早上我发现了一个有趣的问题。我正在更新GAC中的DLL,并使用cmd行方法进行备份。当我尝试上传新的DLL(相同版本号)时,我收到了一个错误,只有在关闭cmd窗口后才消失。花了我几分钟的时间咒骂才找出问题所在! - NeilD

5
我是PowerShell GAC的作者。使用PowerShell GAC,您可以从GAC中提取程序集,而不依赖于GAC内部,如更改文件夹结构。
Get-GacAssembly SomeCompany* | Get-GacAssemblyFile | Copy-Item -Dest C:\Temp\SomeCompany

3
这篇MSDN博客文章介绍了从全局程序集缓存(GAC)中提取DLL的三种不同方法。这是目前为止给出的方法的有用总结。

3

我想我找到了一种方法,可以在不修改注册表、使用命令行、PowerShell或任何其他程序的情况下查看GAC内部:

创建一个新快捷方式(指向任何地方)。然后修改该快捷方式的目标为:

%windir%\assembly\GAC_MSIL\System

打开此快捷方式,可直接进入GAC中的系统文件夹(每个人都应该有),并具有让您切换到更高级目录,然后浏览任何其他文件夹(以及查看dll文件等)的奇妙副作用。

我已在Windows 7和Windows Server 2012上进行了测试。

注意:无法在创建快捷方式时使用此目标,但可以在编辑时使用。

享受吧!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接