12

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

7 回答 7

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

希望这可以帮助某人...

于 2014-01-14T05:14:41.960 回答
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.GacRemove(assemblyFullPath);

希望它会帮助你

于 2012-09-07T09:41:16.190 回答
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;
}
于 2012-11-18T13:20:46.967 回答
1

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

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

于 2012-09-05T09:36:01.920 回答
0

为什么不直接从应用程序中调用“gacutil /u”?还是我错过了什么?

于 2012-10-28T15:25:24.013 回答
0

您可以查看 .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 中并且该类被标记为内部,您可以使用反射来访问它。看

如何使用反射访问内部类

于 2014-10-08T01:53:45.580 回答
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/

于 2012-09-18T23:26:10.997 回答