在 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 卸载的主要内容,如果未能解决你的问题,请参考以下文章

GAC(Global Assembly Cache)注册/卸载 dll

如何在托管代码(C#)中从本机代码(C++)获取字符串数组

在 WP8 中从 C++ 代码调用 C# 方法

在 C# 中从 XML Schema 生成代码的限制是啥?

如何在 C# 代码中从本地存储中检索值?

在 WebBrowser 的文档中从 JavaScript 调用 C# 代码