从GAC中卸载C#代码

时间:2012-06-20 09:56:18

标签: c# gac uninstall

如何从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;
}

7 个答案:

答案 0 :(得分:2)

假设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);
}

希望这有助于某人...

答案 1 :(得分:1)

你为什么要这样做? GAC是全局程序集缓存,基本上是包含PC的共享DLL的系统文件夹。

如果您想要删除程序集,请查看此处的gacutil文档: http://msdn.microsoft.com/en-us/library/ex0ss12c(v=vs.71).aspx 但它将被删除所有项目!

答案 2 :(得分:1)

请按照以下步骤操作: -

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文件的方法。按照以下步骤安装/删除文件:

  1. 在项目中添加对System.EnterpriseServices.dll的引用。
  2. 使用System.EnterpriseServices.Internal添加;在使用部分的末尾。
  3. 现在使用assemblyFullPath,在您要删除汇编文件的方法中添加以下代码行。

    发布publishProcess = new Publish(); publishProcess.GacRemove(assemblyFullPath);

  4. 希望它会帮助你

答案 3 :(得分:1)

建议您不要这样做,因为它可能会导致使用该DLL的其他应用程序出现问题。但我认为它是你自己的,所以它相对安全。

使用下一个代码从GAC中删除dll。 asssembly名称是没有扩展名的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;
}

答案 4 :(得分:0)

如何在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/

答案 5 :(得分:0)

为什么不从应用程序中调用“gacutil / u”?或者我错过了什么?

答案 6 :(得分:0)

您可以看到.NET参考代码,详细了解如何以编程方式完成(尽管参考站点的许可证将限制您在自己的软件中使用它,即复制粘贴此代码不是一个好主意)。

http://referencesource.microsoft.com/#System.Web/xsp/system/Web/Configuration/GacUtil.cs

(向下滚动到公共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