以编程方式检查程序集是否在本地计算机上的 GAC(全局程序集缓存)中注册的最简单方法是什么? 是否有一些易于使用的 .NET API,我可以在其中为其提供程序集 DLL 或程序集对象本身的位置,以检查它是否存在于本地计算机上的 GAC 中? 就我而言,我正在检查的程序集已经加载到程序检查的当前AppDomain中,因此我不确定调用Assembly.ReflectionOnlyLoad
并捕获异常是否会像我在其他帖子中看到的那样工作,而且这似乎有点笨拙。
理想情况下,我想避免调用像gacutil.exe
这样的外部可执行文件进行检查。
这个问题与以下问题非常相似,但我的问题更精确一些,而且两者都没有一个公认的答案,也没有一个提供的答案似乎不完整或最佳:
- 检查程序集的 GAC
- 以编程方式检查 gac 中是否存在 dll。如果是这样,请在网格中显示它
最初我认为以下方法是最好的方法,但除非您指定程序集的全名,否则它不起作用,并且由于尝试/捕获而有点笨拙,但它很简单并且适用于许多情况:
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 进行尝试/捕获即可工作。 这是一堆代码,但它适用于部分程序集名称:
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(' ', 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;
}
}
检查代码库是否为空
if (asm.CodeBase == null) {
// IN GAC
}