/// <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(AssemblyReference assemblyReference){ if (assemblyReference == null) { Debug.Fail("assemblyReference == null"); return null; } lock(GlobalAssemblyCache.Lock){ if (!GlobalAssemblyCache.FusionLoaded){ GlobalAssemblyCache.FusionLoaded = true; System.Reflection.Assembly systemAssembly = typeof(object).Assembly; //^ assume systemAssembly != null && systemAssembly.Location != null; string dir = Path.GetDirectoryName(systemAssembly.Location); //^ assume dir != null; GlobalAssemblyCache.LoadLibrary(Path.Combine(dir, "fusion.dll")); } IAssemblyEnum assemblyEnum; CreateAssemblyEnum(out assemblyEnum, null, null, ASM_CACHE.GAC, 0); if (assemblyEnum == null) return null; IApplicationContext applicationContext; IAssemblyName currentName; while (assemblyEnum.GetNextAssembly(out applicationContext, out currentName, 0) == 0){ //^ assume currentName != null; AssemblyName aName = new AssemblyName(currentName); if (assemblyReference.Matches(aName.Name, aName.Version, aName.Culture, aName.PublicKeyToken)){ string codeBase = aName.CodeBase; if (codeBase != null && codeBase.StartsWith("file:///")) return codeBase.Substring(8); return aName.GetLocation(); } } return null; } }
/// <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(AssemblyReference assemblyReference) { if (assemblyReference == null) { Debug.Fail("assemblyReference == null"); return(null); } lock (GlobalAssemblyCache.Lock) { if (!GlobalAssemblyCache.FusionLoaded) { GlobalAssemblyCache.FusionLoaded = true; System.Reflection.Assembly systemAssembly = typeof(object).Assembly; //^ assume systemAssembly != null && systemAssembly.Location != null; string dir = Path.GetDirectoryName(systemAssembly.Location); //^ assume dir != null; GlobalAssemblyCache.LoadLibrary(Path.Combine(dir, "fusion.dll")); } IAssemblyEnum assemblyEnum; CreateAssemblyEnum(out assemblyEnum, null, null, GAC, 0); if (assemblyEnum == null) { return(null); } IApplicationContext applicationContext; IAssemblyName currentName; while (assemblyEnum.GetNextAssembly(out applicationContext, out currentName, 0) == 0) { //^ assume currentName != null; AssemblyName aName = new AssemblyName(currentName); if (assemblyReference.Matches(aName.Name, aName.Version, aName.Culture, aName.PublicKeyToken)) { string codeBase = aName.CodeBase; if (codeBase != null && codeBase.StartsWith("file:///")) { return(codeBase.Substring(8)); } return(aName.GetLocation()); } } return(null); } }
internal AssemblyNode/*!*/ GetAssemblyFromReference(AssemblyReference/*!*/ assemblyReference) { lock (this) { if (SystemAssemblyLocation.ParsedAssembly != null && (assemblyReference.Name == "mscorlib" || assemblyReference.Name == "basetypes" || assemblyReference.Name == "ioconfig" || assemblyReference.Name == "singularity.v1")) return SystemAssemblyLocation.ParsedAssembly; if (CoreSystemTypes.SystemAssembly != null && CoreSystemTypes.SystemAssembly.Name == assemblyReference.Name) return CoreSystemTypes.SystemAssembly; string strongName = null; object cachedValue = null; if (assemblyReference.PublicKeyOrToken == null || assemblyReference.PublicKeyOrToken.Length == 0) { if (assemblyReference.Location != null) cachedValue = this.localAssemblyCache[assemblyReference.Location]; if (cachedValue == null) { cachedValue = this.localAssemblyCache[assemblyReference.Name]; if (cachedValue != null && assemblyReference.Location != null) this.localAssemblyCache[assemblyReference.Location] = cachedValue; } } else { strongName = assemblyReference.StrongName; if (this.useStaticCache) { //See if reference is to an assembly that lives in the GAC. if (assemblyReference.Location != null) cachedValue = Reader.StaticAssemblyCache[assemblyReference.Location]; if (cachedValue == null) cachedValue = Reader.StaticAssemblyCache[strongName]; } if (cachedValue == null) cachedValue = this.localAssemblyCache[strongName]; } if (cachedValue == null) { //See if assembly is a platform assembly (and apply unification) AssemblyReference aRef = (AssemblyReference)TargetPlatform.AssemblyReferenceFor[Identifier.For(assemblyReference.Name).UniqueIdKey]; if (aRef != null && assemblyReference.Version != null && aRef.Version >= assemblyReference.Version && aRef.MatchesIgnoringVersion(assemblyReference)) { AssemblyNode platformAssembly = aRef.assembly; if (platformAssembly == null) { Debug.Assert(aRef.Location != null); platformAssembly = AssemblyNode.GetAssembly(aRef.Location, this.doNotLockFile, this.getDebugSymbols, this.useStaticCache); } if (platformAssembly != null) { if (strongName == null) strongName = assemblyReference.Name; lock (Reader.StaticAssemblyCache) { if (aRef.Location != null) Reader.StaticAssemblyCache[aRef.Location] = platformAssembly; Reader.StaticAssemblyCache[strongName] = platformAssembly; } return aRef.assembly = platformAssembly; } } } AssemblyNode assembly = cachedValue as AssemblyNode; if (assembly != null) goto done; //No cached assembly and no cached reader for this assembly. Look for a resolver. if (this.module != null) { assembly = this.module.Resolve(assemblyReference); if (assembly != null) { if (strongName == null) { this.localAssemblyCache[assembly.Name] = assembly; if (assembly.Location != null) this.localAssemblyCache[assembly.Location] = assembly; } else { if (CoreSystemTypes.SystemAssembly != null && CoreSystemTypes.SystemAssembly.Name == assembly.Name) return CoreSystemTypes.SystemAssembly; lock (Reader.StaticAssemblyCache) { if (this.useStaticCache) { if (assembly.Location != null) Reader.StaticAssemblyCache[assembly.Location] = assembly; Reader.StaticAssemblyCache[strongName] = assembly; } else { this.localAssemblyCache[strongName] = assembly; if (assembly.Location != null) this.localAssemblyCache[assembly.Location] = assembly; } } } goto done; } } //Look for an assembly with the given name in the same directory as the referencing module if (this.directory != null) { string fileName = System.IO.Path.Combine(this.directory, assemblyReference.Name + ".dll"); if (System.IO.File.Exists(fileName)) { assembly = AssemblyNode.GetAssembly(fileName, this.localAssemblyCache, this.doNotLockFile, this.getDebugSymbols, this.useStaticCache); if (assembly != null) { if (strongName == null) goto cacheIt; //found something //return assembly only if it matches the strong name of the reference if (assemblyReference.Matches(assembly.Name, assembly.Version, assembly.Culture, assembly.PublicKeyToken)) goto cacheIt; } } fileName = System.IO.Path.Combine(this.directory, assemblyReference.Name + ".exe"); if (System.IO.File.Exists(fileName)) { assembly = AssemblyNode.GetAssembly(fileName, this.localAssemblyCache, this.doNotLockFile, this.getDebugSymbols, this.useStaticCache); if (assembly != null) { if (strongName == null) goto cacheIt; //found something //return assembly only if it matches the strong name of the reference if (assemblyReference.Matches(assembly.Name, assembly.Version, assembly.Culture, assembly.PublicKeyToken)) goto cacheIt; } } fileName = System.IO.Path.Combine(this.directory, assemblyReference.Name + ".ill"); if (System.IO.File.Exists(fileName)) { assembly = AssemblyNode.GetAssembly(fileName, this.localAssemblyCache, this.doNotLockFile, this.getDebugSymbols, this.useStaticCache); if (assembly != null) { if (strongName == null) goto cacheIt; //found something //return assembly only if it matches the strong name of the reference if (assemblyReference.Matches(assembly.Name, assembly.Version, assembly.Culture, assembly.PublicKeyToken)) goto cacheIt; } } } //Look for an assembly in the same directory as the application using Reader. { string fileName = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, assemblyReference.Name + ".dll"); if (System.IO.File.Exists(fileName)) { assembly = AssemblyNode.GetAssembly(fileName, this.localAssemblyCache, this.doNotLockFile, this.getDebugSymbols, this.useStaticCache); if (assembly != null) { if (strongName == null) goto cacheIt; //found something //return assembly only if it matches the strong name of the reference if (assemblyReference.Matches(assembly.Name, assembly.Version, assembly.Culture, assembly.PublicKeyToken)) goto cacheIt; } } fileName = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, assemblyReference.Name + ".exe"); if (System.IO.File.Exists(fileName)) { assembly = AssemblyNode.GetAssembly(fileName, this.localAssemblyCache, this.doNotLockFile, this.getDebugSymbols, this.useStaticCache); if (assembly != null) { if (strongName == null) goto cacheIt; //found something //return assembly only if it matches the strong name of the reference if (assemblyReference.Matches(assembly.Name, assembly.Version, assembly.Culture, assembly.PublicKeyToken)) goto cacheIt; } } } assembly = null; //Probe the GAC string gacLocation = null; if (strongName != null) { //Look for the assembly in the system's Global Assembly Cache gacLocation = GlobalAssemblyCache.GetLocation(assemblyReference); if (gacLocation != null && gacLocation.Length == 0) gacLocation = null; if (gacLocation != null) { assembly = AssemblyNode.GetAssembly(gacLocation, this.useStaticCache ? Reader.StaticAssemblyCache : this.localAssemblyCache, this.doNotLockFile, this.getDebugSymbols, this.useStaticCache); if (assembly != null) { lock (Reader.StaticAssemblyCache) { if (this.useStaticCache) { Reader.StaticAssemblyCache[gacLocation] = assembly; Reader.StaticAssemblyCache[strongName] = assembly; } else { this.localAssemblyCache[gacLocation] = assembly; this.localAssemblyCache[strongName] = assembly; } } } } } goto done; cacheIt: if (strongName == null) { this.localAssemblyCache[assembly.Name] = assembly; if (assembly.Location != null) this.localAssemblyCache[assembly.Location] = assembly; } else { this.localAssemblyCache[strongName] = assembly; if (assembly.Location != null) this.localAssemblyCache[assembly.Location] = assembly; } done: if (assembly != null) assembly.InitializeAssemblyReferenceResolution(this.module); if (assembly == null) { if (this.module != null) { assembly = this.module.ResolveAfterProbingFailed(assemblyReference); if (assembly != null) goto cacheIt; HandleError(this.module, String.Format(CultureInfo.CurrentCulture, ExceptionStrings.AssemblyReferenceNotResolved, assemblyReference.StrongName)); } assembly = new AssemblyNode(); assembly.Culture = assemblyReference.Culture; assembly.Name = assemblyReference.Name; assembly.PublicKeyOrToken = assemblyReference.PublicKeyOrToken; assembly.Version = assemblyReference.Version; assembly.Location = "unknown:location"; goto cacheIt; } return assembly; } }