/// <summary> /// Determines whether the GAC contains the specified code base URI. /// </summary> /// <param name="codeBaseUri">The code base URI.</param> public static bool Contains(Uri codeBaseUri) { Contract.Requires(codeBaseUri != null); lock (GlobalLock.LockingObject) { #if COMPACTFX var gacKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"\Software\Microsoft\.NETCompactFramework\Installer\Assemblies\Global"); if (gacKey == null) return false; var codeBase = codeBaseUri.AbsoluteUri; foreach (var gacName in gacKey.GetValueNames()) { var values = gacKey.GetValue(gacName) as string[]; if (values == null || values.Length == 0) continue; if (string.Equals(values[0], codeBase, StringComparison.OrdinalIgnoreCase)) return true; if (values.Length > 1 && string.Equals(values[1], codeBase, StringComparison.OrdinalIgnoreCase)) return true; } return false; #else #if __MonoCS__ IAssemblyEnum assemblyEnum = new MonoAssemblyEnum(); #else if (!GlobalAssemblyCache.FusionLoaded) { GlobalAssemblyCache.FusionLoaded = true; var systemAssembly = typeof(object).Assembly; var systemAssemblyLocation = systemAssembly.Location; string dir = Path.GetDirectoryName(systemAssemblyLocation)??""; GlobalAssemblyCache.LoadLibrary(Path.Combine(dir, "fusion.dll")); } IAssemblyEnum assemblyEnum; int rc = GlobalAssemblyCache.CreateAssemblyEnum(out assemblyEnum, null, null, ASM_CACHE.GAC, 0); if (rc < 0 || assemblyEnum == null) return false; #endif IApplicationContext applicationContext; IAssemblyName currentName; while (assemblyEnum.GetNextAssembly(out applicationContext, out currentName, 0) == 0) { //^ assume currentName != null; AssemblyName assemblyName = new AssemblyName(currentName); string/*?*/ scheme = codeBaseUri.Scheme; if (scheme != null && assemblyName.CodeBase.StartsWith(scheme, StringComparison.OrdinalIgnoreCase)) { try { Uri foundUri = new Uri(assemblyName.CodeBase); if (codeBaseUri.Equals(foundUri)) return true; } catch (System.ArgumentNullException) { } catch (System.UriFormatException) { } } } return false; #endif } }
/// <summary> /// Returns the original location of the corresponding assembly if available, otherwise returns the location of the shadow copy. /// If the corresponding assembly is not in the GAC, null is returned. /// </summary> public static string/*?*/ GetLocation(AssemblyIdentity assemblyIdentity, IMetadataHost metadataHost) { lock (GlobalLock.LockingObject) { #if COMPACTFX var gacKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"\Software\Microsoft\.NETCompactFramework\Installer\Assemblies\Global"); foreach (var gacName in gacKey.GetValueNames()) { if (IdentityMatchesString(assemblyIdentity, gacName)) { var values = gacKey.GetValue(gacName) as string[]; if (values == null || values.Length == 0) continue; return values[0]; } } return null; #else #if __MonoCS__ IAssemblyEnum assemblyEnum = new MonoAssemblyEnum(); #else if (!GlobalAssemblyCache.FusionLoaded) { GlobalAssemblyCache.FusionLoaded = true; var systemAssembly = typeof(object).Assembly; var systemAssemblyLocation = systemAssembly.Location; var dir = Path.GetDirectoryName(systemAssemblyLocation)??""; GlobalAssemblyCache.LoadLibrary(Path.Combine(dir, "fusion.dll")); } IAssemblyEnum assemblyEnum; int rc = CreateAssemblyEnum(out assemblyEnum, null, null, ASM_CACHE.GAC, 0); if (rc < 0 || assemblyEnum == null) return null; #endif IApplicationContext applicationContext; IAssemblyName currentName; while (assemblyEnum.GetNextAssembly(out applicationContext, out currentName, 0) == 0) { //^ assume currentName != null; AssemblyName cn = new AssemblyName(currentName); if (assemblyIdentity.Equals(new AssemblyIdentity(metadataHost.NameTable.GetNameFor(cn.Name), cn.Culture, cn.Version, cn.PublicKeyToken, ""))) { string codeBase = cn.CodeBase; if (codeBase != null && codeBase.StartsWith("file://", StringComparison.OrdinalIgnoreCase)) { Uri u = new Uri(codeBase, UriKind.Absolute); return u.LocalPath; } return cn.GetLocation(); } } return null; #endif } }