在Windows Server 2008 .NET 4.0中将DLL拖放到GAC(“程序集”)

34
我在尝试将一些代码部署到客户机器上,但不想安装MS Windows SDK工具。这意味着我无法访问"gacutil"。我也没有为我的代码创建安装程序,似乎这可能是.net 4.0中的唯二选择。
过去,我会简单地转到“开始”,运行,输入“assembly”,然后拖放我的dll文件进去。
这还有可能吗?当我尝试这样做时,没有错误信息,但是dll文件未出现在“assembly”文件夹中。当我在开发机上使用gacutil时,它可以正常工作,但dll文件仍未出现。

不,允许在 .NET 2-3.5 时代进行的 shell 扩展现在已不再部署在 .NET 4 中。现在将程序集安装到 GAC 中需要一个真正的安装程序。或者只需进行应用程序本地部署,这总是更好的选择,除非您是需要分发安全更新的大型公司。 - Hans Passant
什么是“应用程序本地部署”?该代码是对我有限控制的较大应用程序的修改。该应用程序要求将代码放置在GAC中。 - TizzyFoe
http://sharepointbulletin.blogspot.co.uk/2013/06/right-way-of-installing-assembly-into.html - Muhammad Raja
7个回答

57

在 .net 4.0 中,微软取消了通过拖放方式将DLL添加到程序集的功能。

相反,您需要使用gacutil.exe或创建安装程序来执行此操作。 实际上,微软不建议使用gacutil,但我还是选择了这种方法。

要在开发计算机上使用gacutil,请转到:
开始 -> 程序 -> Microsoft Visual studio 2010 -> Visual Studio Tools -> Visual Studio Command Prompt (2010)

然后使用以下命令进行卸载和重新安装。请注意,卸载命令中未包括 .dll
gacutil /u myDLL
gacutil /i "C:\Program Files\Custom\myDLL.dll"

要在非开发计算机上使用Gacutil,您必须从开发计算机复制可执行文件和配置文件到生产计算机。看起来有几个不同版本的Gacutil。对我有效的一个版本在此处找到:
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\gacutil.exe C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\gacutil.exe.config

将文件复制到此位置或适当的 .net 文件夹中;
C:\Windows\Microsoft.NET\Framework\v4.0.30319

然后使用以下命令进行卸载和重新安装
"C:\Users\BHJeremy\Desktop\Installing to the Gac in .net 4.0\gacutil.exe" /u "myDLL"

"C:\Windows\Microsoft.NET\Framework\v4.0.30319\gacutil.exe" /i "C:\Program Files\Custom\myDLL.dll"


2
还要注意的是,GAC 是针对不同的 CLR 进行分割的。.NET 4 的位置是 %windir%\Microsoft.NET\assembly\ - Chris
8
那些混蛋!(虚荣地但是开玩笑地)他们为什么要删除那个功能?这是一个完全合法的添加GACs的方式。难过的表情 - Chiramisu
2
你能否编辑,包括如下罗伯托建议的复制 gacutlrc.dll? - Christopher Scott
我很高兴他们移除了拖放功能。使用gacutil要容易得多。/s - 99823

23

在我的情况下,我需要复制gacutil.exe,gacutil.exe.config以及gacutlrc.dll(从1033目录中)


2
谢谢,是的,这也对我有用。我将gacutlrc.dll复制到服务器上与gacutil.exe相同的文件夹中,这次成功注册了dll。 - Michael Cox
1033目录存储在哪里?我找不到它。 - Trismegistos
它在 C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\1033 - chridam

5

gacutil实用程序在客户机上不可用,且Window SDK许可证禁止将其分发给您的客户。当您的客户无法、不会(而且确实不应该)在安装过程中下载300MB的Windows SDK时。

有一种官方支持的API可以用于在全局程序集缓存中注册程序集,您(或安装程序)可以使用此API。Microsoft的Windows Installer技术知道如何为您调用此API。您必须参考您的MSI安装程序工具(例如WiX,InnoSetup)的语法,以指示您希望在全局程序集缓存中注册程序集。

但是MSI和gacutil并没有做什么特别的事情。他们只是调用您自己可以调用的相同API。有关通过代码注册程序集的文档,请参见:

KB317540:DOC:未在.NET Framework软件开发工具包(SDK)文档中记录全局程序集缓存(GAC)API

var IAssemblyCache assemblyCache;
CreateAssemblyCache(ref assemblyCache, 0);


String manifestPath = "D:\Program Files\Contoso\Frobber\Grob.dll";

FUSION_INSTALL_REFERENCE refData;
refData.cbSize = SizeOf(refData); //The size of the structure in bytes
refData.dwFlags = 0; //Reserved, must be zero
refData.guidScheme = FUSION_REFCOUNT_FILEPATH_GUID; //The assembly is referenced by an application that is represented by a file in the file system. The szIdentifier field is the path to this file.
refData.szIdentifier = "D:\Program Files\Contoso\Frobber\SuperGrob.exe"; //A unique string that identifies the application that installed the assembly
refData.szNonCannonicalData = "Super cool grobber 9000"; //A string that is only understood by the entity that adds the reference. The GAC only stores this string

//Add a new assembly to the GAC. 
//The assembly must be persisted in the file system and is copied to the GAC.
assemblyCache.InstallAssembly(
      IASSEMBLYCACHE_INSTALL_FLAG_FORCE_REFRESH, //The files of an existing assembly are overwritten regardless of their version number
      manifestPath, //A string pointing to the dynamic-linked library (DLL) that contains the assembly manifest. Other assembly files must reside in the same directory as the DLL that contains the assembly manifest.
      refData);

更多在KB文章被删除之前的文档:
该结构体的字段定义如下: - cbSize - 结构体的大小(字节) - dwFlags - 保留字段,必须为零 - guidScheme - 添加引用的实体 - szIdentifier - 标识安装程序集的应用程序的唯一字符串 - szNonCannonicalData - 只有添加引用的实体可以理解的字符串。GAC只存储此字符串。
guidScheme字段的可能值如下: - FUSION_REFCOUNT_MSI_GUID - 应用了Windows Installer安装程序的应用程序引用此程序集。 szIdentifier字段设置为MSI,szNonCannonicalData设置为Windows Installer。此方案仅由Windows Installer自身使用。 - FUSION_REFCOUNT_UNINSTALL_SUBKEY_GUID - 此应用程序出现在“添加/删除程序”中, 引用了此程序集。 szIdentifier字段是用于向“添加/删除程序”注册该应用程序的标记。 - FUSION_REFCOUNT_FILEPATH_GUID- 引用了表示文件系统中文件的应用程序的此程序集。 szIdentifier字段是指向该文件的路径。 - FUSION_REFCOUNT_OPAQUE_STRING_GUID - 只有由不透明字符串表示的应用程序引用此程序集。 szIdentifier是这个不透明字符串。当您删除此内容时,GAC不会执行存在性检查。

3
如果您已经安装了必要的.NET框架,例如.NET 4.0或.NET 3.5,则可以从任何计算机上复制Gacutil.exe到新计算机。
以下是操作步骤: 1)以管理员身份打开新服务器中的CMD。 2)转到您复制Gacutil.exe的文件夹,例如C:\program files。(在我的情况下) 3)在命令提示符中键入以下内容并安装。
C:\ Program Files \ gacutil.exe / I dllname

2

除了安装程序和gacutil之外,还有一些图形界面工具可供选择,比如Gac ManagerGACAdmin。如果你喜欢PowerShell,你可以使用我编写的PowerShell GAC


哇,GAC 管理器真是太棒了。非常感谢你。 - vbullinger

1
请注意,Fusion API 是未托管的。当前参考文档在这里:开发指南 > 未托管 API 参考 > Fusion 但是,有一种托管方法可以将程序集添加到 GAC 中: System.EnterpriseServices.Internal.Publish.GacInstall 如果需要注册任何类型: System.EnterpriseServices.Internal.Publish.RegisterAssembly
发布类的参考文档在这里:.NET Framework 类库 > System.EnterpriseServices 命名空间 > System.EnterpriseServices.Internal 然而,这些方法是为安装Web服务应用程序(如ASP.NET或WCF)所需的组件而设计的。因此,它们不会向Fusion注册程序集;因此,它们可以被其他应用程序或使用gacutil卸载,并导致您的程序集停止工作。因此,如果您在Web服务器之外使用它们,管理员正在管理GAC,请务必将应用程序引用添加到SOFTWARE\Wow6432Node\Microsoft\Fusion\References(64位操作系统)或SOFTWARE\Microsoft\Fusion\References(32位操作系统)中,以便除非他们卸载您的应用程序,否则没有人可以删除您的支持程序集。

你为什么在这里? - Jürgen Steinblock

-2

您也可以使用命令提示符将文件复制到GAC。我使用以下批处理脚本来复制DLL并重新启动IIS。

copy /b/v/y "PathToAssembly\MyAssembly.dll" "C:\Windows\assembly\" 
iisreset /noforce
pause

节省了使用或安装gacutil的需求


这不是正确的。在那个文件夹中有一个文件夹结构,你必须使用它。而且正确的文件夹也取决于 .Net 版本。 - Lars Truijens
还有一个问题,它是复制还是安装?我测试了一下,但它没有出现在GAC中,但文件仍然存在。我不知道为什么这个答案被投票否决了? - Steve Lam

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