如何以编程方式确定.NET程序集安装在GAC? [英] How to programmatically determine if .NET assembly is installed in GAC?

查看:167
本文介绍了如何以编程方式确定.NET程序集安装在GAC?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是检查编程如果一个组件在GAC(全局程序集缓存)注册的本地计算机上的最简单的方法?有一些易于使用的.NET API,我可以给它一个位置,一个集DLL或组件对象本身来检查它是否存在于GAC在本地机器上?就我而言,我检查装置将已经在程序检查,所以我不知道叫 Assembly.ReflectionOnlyLoad 和捕获异常将当前工作的AppDomain中加载像我见过的其他职位建议,再加上似乎有种哈克。

What's the easiest way to check programmatically if an assembly is registered in the GAC (Global Assembly Cache) on the local machine? Is there some easy to use .NET API where I can give it a location to an assembly DLL or an Assembly object itself to check if it exists in GAC on the local machine? In my case the assembly I'm checking will already be loaded in the current AppDomain of the program checking so I'm not sure calling Assembly.ReflectionOnlyLoad and catching an exception will work like I've seen suggested in other posts, plus that seems kind of hacky.

在理想情况下,我想避免调用外部可执行如的Gacutil.exe 检查。

Ideally I'd like to avoid calling an external executable like gacutil.exe to check.

推荐答案

这个问题很类似下面的问题,但我的是多了几分precise,再加上既没有一个公认的答案,并没有提供答案似乎完整或最佳:

This question is very similar to the following questions but mine is a little more precise, plus neither had an accepted answer and none of the answers offered seemed complete or optimal:

  • 检查GAC程序集
  • <一个href="http://stackoverflow.com/questions/3356207/programmatically-to-check-dll-exists-in-gac-or-not-if-so-display-it-in-grid">Programmatically要检查DLL存在于加克或not.If因此在网格中显示它
  • Check GAC for an assembly
  • Programmatically To check dll exists in Gac or not.If so display it in grid

原本我以为下面是最好的方法,但它不工作,除非你指定的程序集的全名,它是一种哈克东阳的try / catch语句,但它的简单,适用于许多情况:

Originally I thought the following was the best approach but it doesn't work unless you specify the full name of the assembly and it's kind of hacky beacause of the try/catch but it's simple and works for many cases:

public static class GacUtil
{
    public static bool IsAssemblyInGAC(string assemblyFullName)
    {
        try
        {
            return Assembly.ReflectionOnlyLoad(assemblyFullName)
                           .GlobalAssemblyCache;
        }
        catch
        {
            return false;
        }
    }

    public static bool IsAssemblyInGAC(Assembly assembly)
    {
        return assembly.GlobalAssemblyCache;
    }
}

这是一个更好的方法,通过使用融合API 工程没有一个try / catch 。这是一群更code,但它的工作原理与部分程序集名称:

This is a better approach that works without a try/catch by using the Fusion API. It's a bunch more code but it works with partial assembly names:

public static class GacUtil
{
    [DllImport("fusion.dll")]
    private static extern IntPtr CreateAssemblyCache(
        out IAssemblyCache ppAsmCache, 
        int reserved);

    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("e707dcde-d1cd-11d2-bab9-00c04f8eceae")]
    private interface IAssemblyCache
    {
        int Dummy1();

        [PreserveSig()]
        IntPtr QueryAssemblyInfo(
            int flags, 
            [MarshalAs(UnmanagedType.LPWStr)] string assemblyName, 
            ref AssemblyInfo assemblyInfo);

        int Dummy2();
        int Dummy3();
        int Dummy4();
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct AssemblyInfo
    {
        public int cbAssemblyInfo;
        public int assemblyFlags;
        public long assemblySizeInKB;

        [MarshalAs(UnmanagedType.LPWStr)]
        public string currentAssemblyPath;

        public int cchBuf;
    }

    public static bool IsAssemblyInGAC(string assemblyName)
    {
        var assembyInfo = new AssemblyInfo { cchBuf = 512 };
        assembyInfo.currentAssemblyPath = new string('\0', assembyInfo.cchBuf);

        IAssemblyCache assemblyCache;

        var hr = CreateAssemblyCache(out assemblyCache, 0);

        if (hr == IntPtr.Zero)
        {
            hr = assemblyCache.QueryAssemblyInfo(
                1, 
                assemblyName, 
                ref assembyInfo);

            if (hr != IntPtr.Zero)
            {
                return false;
            }

            return true;
        }

        Marshal.ThrowExceptionForHR(hr.ToInt32());
        return false;
    }
}

这篇关于如何以编程方式确定.NET程序集安装在GAC?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆