在 C# 代码中从 GAC 卸载
Posted
技术标签:
【中文标题】在 C# 代码中从 GAC 卸载【英文标题】:Uninstall from GAC In C# code 【发布时间】:2012-06-22 10:35:27 【问题描述】:如何从我的 C# 应用程序中卸载 GAC。
我无法从 GAC 卸载特定的 exe 和 DLL。
在 C# 中卸载 GAC 是否正确?
public void RemoveAssembly(string ShortAssemblyName, string PublicToken)
AssemblyCacheEnum AssembCache = new AssemblyCacheEnum(null);
string FullAssembName = null;
for (; ; )
string AssembNameLoc = AssembCache.GetNextAssembly();
if (AssembNameLoc == null)
break;
string Pt;
string ShortName = GetAssemblyShortName(AssembNameLoc, out Pt);
if (ShortAssemblyName == ShortName)
if (PublicToken != null)
PublicToken = PublicToken.Trim().ToLower();
if (Pt == null)
FullAssembName = AssembNameLoc;
break;
Pt = Pt.ToLower().Trim();
if (PublicToken == Pt)
FullAssembName = AssembNameLoc;
break;
else
FullAssembName = AssembNameLoc;
break;
string Stoken = "null";
if (PublicToken != null)
Stoken = PublicToken;
if (FullAssembName == null)
throw new Exception("Assembly=" + ShortAssemblyName + ",PublicToken=" +
token + " not found in GAC");
AssemblyCacheUninstallDisposition UninstDisp;
AssemblyCache.UninstallAssembly(FullAssembName, null, out UninstDisp);
public static void UninstallAssembly(String assemblyName, InstallReference reference, out AssemblyCacheUninstallDisposition disp)
AssemblyCacheUninstallDisposition dispResult = AssemblyCacheUninstallDisposition.Uninstalled;
if (reference != null)
if (!InstallReferenceGuid.IsValidGuidScheme(reference.GuidScheme))
throw new ArgumentException("Invalid reference guid.", "guid");
IAssemblyCache ac = null;
int hr = Utils.CreateAssemblyCache(out ac, 0);
if (hr >= 0)
hr = ac.UninstallAssembly(0, assemblyName, reference, out dispResult);
if (hr < 0)
Marshal.ThrowExceptionForHR(hr);
disp = dispResult;
【问题讨论】:
你会考虑通过 Process 类注销它吗? 见***.com/a/2611435/17034 "C# Source Code: Programmatically adding and removing assemblies from the GAC (without using GACUTIL)" 如果您实际上不需要以编程方式删除,也可以通过导航到 C:\Windows\assembly 并“删除”要删除的程序集来手动执行此操作。 “C# 源代码:以编程方式在 GAC 中添加和删除程序集(不使用 GACUTIL)”的链接现在已失效。你可以在archive.org找到这篇文章--C# Source Code: Programmatically adding and removing assemblies from the GAC (without using GACUTIL) 【参考方案1】:建议您不要这样做,因为它可能会导致使用该 dll 的其他应用程序出现问题。不过我估计是你自己的,所以还是比较安全的。
使用下面的代码从 GAC 中删除 dll。程序集名称是您的 dll 的名称,不带扩展名。
public static void UninstallAssembly(string assemblyName)
ProcessStartInfo processStartInfo = new ProcessStartInfo("gacutil.exe",
string.Format("/u 0.dll", assemblyName));
processStartInfo.UseShellExecute = false;
Process process = Process.Start(processStartInfo);
process.WaitForExit;
【讨论】:
Gacutil.exe 仅用于开发目的,不应用于将生产程序集安装到全局程序集缓存中。有关更多信息,请参阅 MSDN msdn.microsoft.com/en-us/library/dkkx7f79(v=vs.110).aspx 问题不是如何将程序集安装到 GAC 中,而是如何删除它们。【参考方案2】:您可以查看 .NET 参考代码以了解有关如何以编程方式完成的详细信息(尽管参考站点的许可证会限制您在自己的软件中使用它,即,复制粘贴此代码不是一个好主意)。
http://referencesource.microsoft.com/#System.Web/xsp/system/Web/Configuration/GacUtil.cs
(向下滚动到 public bool GacUnInstall(string assemblyName))
另见 IAssemblyCache
http://referencesource.microsoft.com/#System.Web/xsp/system/Web/Configuration/IAssemblyCache.cs
以及 GetAssemblyCache 的本机方法
http://referencesource.microsoft.com/#System.Web/xsp/system/Web/NativeMethods.cs
另一方面,由于代码在汇编 System.Web 中,并且该类被标记为内部,因此您可以使用反射来访问它。见
How to access internal class using Reflection
【讨论】:
【参考方案3】:假设 DLL 与运行此代码的目录位于同一目录中,请尝试:
ArrayList libraries = new ArrayList();
libraries.Add("somedll1.dll");
libraries.Add("somedll2.dll");
Console.WriteLine("Registering DDLs in the Gac");
try
for (int i = 0; i < libraries.Count; i++)
// get the path from the running exe, and remove the running exe's name from it
new System.EnterpriseServices.Internal.Publish().GacRemove(System.Reflection.Assembly.GetExecutingAssembly().Location.Replace("ThisUtilitiesName.exe", "") + libraries[i]);
Console.WriteLine("Completed task successfully");
catch (Exception exp)
Console.WriteLine(exp.Message);
希望这对某人有所帮助...
【讨论】:
【参考方案4】:为什么不直接从应用程序中调用“gacutil /u”?还是我错过了什么?
【讨论】:
【参考方案5】:如何在 Visual C# 中将程序集安装到全局程序集缓存中:
这是来自 Microsoft 支持文章的解决方案: http://support.microsoft.com/kb/815808
另一个链接(从 GAC 注册、注销库): http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/7d3165cf-ca3b-43cc-8f77-a46dbf38f13d/
【讨论】:
【参考方案6】:按照以下步骤操作:-
using System;
using System.Reflection;
private string assemblyFullPath = "";
public class myAssembly
static void Main()
Assembly assembly = Assembly.Load("library, version=1.0.0.0, culture=neutral, PublicKeyToken=9b184fc90fb9648d");
assemblyFullPath = assembly.Location;
你也可以使用Assembly类的LoadFrom()方法来加载程序集文件,但是不好用,你可以看一下帖子了解原因。
一旦我们有了 assemblyFullPath,就很容易从 GAC 中卸载/删除该程序集。 System.EnterpriseServices.Internal 命名空间提供了安装或删除 GAC 文件的方法。请按照以下步骤安装/删除文件:
-
在您的项目中添加对 System.EnterpriseServices.dll 的引用。
使用 System.EnterpriseServices.Internal 添加;在使用部分的末尾。
现在使用 assemblyFullPath,在您要删除程序集文件的方法中添加以下代码行。
发布发布过程 = 新发布(); publishProcess.GacRemove(assemblyFullPath);
希望对你有帮助
【讨论】:
【参考方案7】:为什么要这样做? GAC 是全局程序集缓存,基本上是包含您 PC 的共享 DLL 的系统文件夹。
如果您想删除程序集,请在此处查看 gacutil 文档: http://msdn.microsoft.com/en-us/library/ex0ss12c(v=vs.71).aspx 但它将为您的所有项目删除!
【讨论】:
以上是关于在 C# 代码中从 GAC 卸载的主要内容,如果未能解决你的问题,请参考以下文章