/// <summary> /// Localiza o caminho do arquivo. /// </summary> /// <param name="parent"></param> /// <param name="file"></param> /// <param name="extAdd"></param> /// <param name="currentFullName"></param> /// <returns></returns> private string FindPath(AsmData parent, string file, string extAdd, string currentFullName) { string result; PathRedirection redirects; string parentDir = _workingDir; if ((parent != null) && !string.IsNullOrEmpty(parent.Path)) { parentDir = System.IO.Path.GetDirectoryName(parent.Path); } string tmpPath = file + extAdd; if (System.IO.File.Exists(tmpPath)) { return(tmpPath); } tmpPath = System.IO.Path.Combine(parentDir, file + extAdd); if (System.IO.File.Exists(tmpPath)) { return(tmpPath); } string ret = System.IO.Path.Combine(parentDir, file + extAdd); if (!_probingPaths.TryGetValue(parent.AssemblyFullName, out redirects)) { return(ret); } foreach (string currentDir in redirects.Directories) { string targetDir = currentDir; if (!System.IO.Path.IsPathRooted(currentDir)) { targetDir = System.IO.Path.Combine(parentDir, currentDir); } if (System.IO.File.Exists(System.IO.Path.Combine(targetDir, file + extAdd))) { string targetPath = System.IO.Path.Combine(targetDir, file + extAdd); return(targetPath); } } result = ret; return(result); }
/// <summary> /// Analiza o assembly informado. /// </summary> /// <param name="assemblyName"></param> /// <param name="throwWhenMissing"></param> /// <returns></returns> public AsmData AnalyzeRootAssembly(string assemblyName, bool throwWhenMissing) { _cache = new Dictionary <string, AsmData>(); _circularDependencyWarningShown = false; _parentsStack = new Stack <string>(); _workingDir = Environment.CurrentDirectory; string fullPath = System.IO.Path.GetFullPath(assemblyName); AsmData ret = new AsmData(assemblyName, fullPath); var domain = AppDomain.CurrentDomain; try { if (!System.IO.File.Exists(assemblyName)) { ret.Path = ""; ret.Validity = AsmData.AsmValidity.Invalid; ret.AssemblyFullName = ""; return(ret); } System.Reflection.Assembly asm = null; try { using (var stream = System.IO.File.OpenRead(fullPath)) { var raw = new byte[stream.Length]; stream.Read(raw, 0, raw.Length); try { asm = domain.Load(raw); ret.Validity = AsmData.AsmValidity.Valid; } catch (Exception) { asm = System.Reflection.Assembly.ReflectionOnlyLoad(raw); ret.Validity = AsmData.AsmValidity.ReferencesOnly; } } } catch (Exception) { asm = null; ret.Validity = AsmData.AsmValidity.Invalid; } if (asm != null) { ret.AssemblyFullName = asm.FullName; ret.Path = fullPath; ret.Architecture = asm.GetName().ProcessorArchitecture; _currentLoadedArchitecture = ret.Architecture; string tempName = asm.GetName().Name; if (!this.assemblyNameToPathMap.ContainsKey(tempName)) { this.assemblyNameToPathMap.Add(tempName, asm.Location); } string cfgFilePath = Redirection.FindConfigFile(ret.Path); if (!string.IsNullOrEmpty(cfgFilePath) && !_allVersionRedirections.ContainsKey(fullPath)) { var versionRedirections = Redirection.GetVersionRedirections(cfgFilePath); PathRedirection pathRedirections = Redirection.GetPathRedirections(ret.AssemblyFullName, cfgFilePath); _allVersionRedirections.Add(fullPath, versionRedirections); _probingPaths.Add(ret.AssemblyFullName, pathRedirections); } var references = asm.GetReferencedAssemblies().ToList(); var fileName = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(fullPath), string.Format("{0}.XmlSerializers{1}", System.IO.Path.GetFileNameWithoutExtension(fullPath), System.IO.Path.GetExtension(fullPath))); if (System.IO.File.Exists(fileName)) { references.Add(System.Reflection.AssemblyName.GetAssemblyName(fileName)); } _totalReferencedAssemblies = references.Count; _parentsStack.Push(ret.AssemblyFullName); foreach (System.Reflection.AssemblyName asmName in references) { this.AnalyzeAssembly(asmName, ret, domain, throwWhenMissing); _assembliesFinished++; if (_bgWorker != null) { _bgWorker.ReportProgress((100 * _assembliesFinished) / _totalReferencedAssemblies); } } _parentsStack.Pop(); } } finally { } return(ret); }
/// <summary> /// Analiza o assembly informado. /// </summary> /// <param name="asmName"></param> /// <param name="parent"></param> /// <param name="domain"></param> /// <param name="throwWhenMissing"></param> private void AnalyzeAssembly(System.Reflection.AssemblyName asmName, AsmData parent, AppDomain domain, bool throwWhenMissing) { bool redirectionApplied = false; string additionalInfo = string.Empty; System.Reflection.AssemblyName analyzedAssembly = asmName; Dictionary <string, List <Redirection> > asmRedirections = this.GetRedirections(asmName); if (asmRedirections != null) { analyzedAssembly = Redirection.GetCorrectAssemblyName(asmName, asmRedirections); redirectionApplied = analyzedAssembly.Version != asmName.Version; } bool invalid = false; bool isInGac = false; AsmData gacAssemblyData = null; System.Reflection.Assembly asm = null; string file = analyzedAssembly.FullName; try { if (_gac != null) { foreach (AsmData item in _gac) { if (item.AssemblyFullName.Contains(analyzedAssembly.FullName)) { isInGac = true; gacAssemblyData = item; break; } } } } catch (Exception) { } if (_cache.ContainsKey(analyzedAssembly.FullName) && !_parentsStack.Contains(analyzedAssembly.FullName)) { AsmData cachedItem = _cache[analyzedAssembly.FullName]; parent.References.Add(cachedItem); return; } string asmLocation = null; AsmData currentAsmData = null; bool gacAssemblySet = false; if (!isInGac) { string extAdd = ""; if (file.LastIndexOf(", Version=") != -1) { file = file.Substring(0, file.LastIndexOf(", Version=")); } if ((System.IO.Path.GetExtension(file) != ".exe") && (System.IO.Path.GetExtension(file) != ".dll")) { extAdd = ".dll"; } string tmpPath = this.FindPath(parent, file, extAdd, analyzedAssembly.FullName); if (System.IO.File.Exists(tmpPath)) { TryLoad(domain, ref additionalInfo, ref invalid, ref asm, tmpPath); } asmLocation = tmpPath; } else { try { using (var stream = System.IO.File.OpenRead(gacAssemblyData.Path)) { var raw = new byte[stream.Length]; stream.Read(raw, 0, raw.Length); asm = domain.Load(raw); } asmLocation = gacAssemblyData.Path; if (!gacAssemblyData.AssemblyFullName.Contains(asm.FullName) && !asm.FullName.Contains(gacAssemblyData.AssemblyFullName)) { currentAsmData = gacAssemblyData; gacAssemblySet = true; asm = null; } } catch (System.IO.FileNotFoundException ex) { additionalInfo = "File " + ex.FileName + " could not be found."; } catch (System.IO.FileLoadException ex) { additionalInfo = "File " + ex.FileName + " could not be loaded. " + ex.FusionLog; } catch (BadImageFormatException ex) { additionalInfo = "Bad image format. " + ex.ToString() + "\r\n" + ex.FusionLog; } } if (currentAsmData == null) { currentAsmData = new AsmData(analyzedAssembly.Name, (asm == null) ? "" : System.IO.Path.GetFullPath(asmLocation)); currentAsmData.AssemblyFullName = analyzedAssembly.FullName; currentAsmData.Validity = AsmData.AsmValidity.Invalid; currentAsmData.InvalidAssemblyDetails = additionalInfo; currentAsmData.Architecture = this.GetArchitecture(currentAsmData.Path); } if ((!gacAssemblySet && (asm != null)) && (analyzedAssembly.Version != asm.GetName().Version)) { string message = string.Concat(new object[] { "Assembly was found with version ", asm.GetName().Version, " but parent references ", analyzedAssembly.Version }); currentAsmData.AdditionalInfo = message; asm = null; } if ((!gacAssemblySet && (asm != null)) && !invalid) { try { object[] attributes = asm.GetCustomAttributes(typeof(System.Reflection.AssemblyProductAttribute), false); if (attributes.Length > 0) { currentAsmData.AssemblyProductName = ((System.Reflection.AssemblyProductAttribute)attributes[0]).Product; } } catch (InvalidOperationException) { currentAsmData.AssemblyProductName = "Product name could not be read."; } catch (System.IO.FileNotFoundException) { currentAsmData.AssemblyProductName = "Product name could not be read. Assembly was loaded but later could not be found."; } catch (Exception ex) { currentAsmData.AssemblyProductName = "Product name could not be read. Error: " + ex.Message; } } parent.References.Add(currentAsmData); if (invalid) { currentAsmData.Validity = AsmData.AsmValidity.ReferencesOnly; } if (_parentsStack.Contains(analyzedAssembly.FullName)) { string circ = this.GetParentsString(); currentAsmData.Validity = AsmData.AsmValidity.CircularDependency; if (!_circularDependencyWarningShown) { _circularDependencyWarningShown = true; } return; } if (asm != null) { currentAsmData.Path = asmLocation; currentAsmData.AssemblyFullName = asm.FullName; if (!invalid) { currentAsmData.Validity = redirectionApplied ? AsmData.AsmValidity.Redirected : AsmData.AsmValidity.Valid; currentAsmData.OriginalVersion = redirectionApplied ? asmName.Version.ToString() : string.Empty; } if (((asm.CodeBase != null) && System.Runtime.InteropServices.RuntimeEnvironment.FromGlobalAccessCache(asm)) && (currentAsmData.AssemblyProductName == "Microsoft\x00ae .NET Framework")) { return; } if ((currentAsmData.Validity != AsmData.AsmValidity.Invalid) && !this.ApplyArchitecture(currentAsmData.Architecture)) { currentAsmData.Validity = AsmData.AsmValidity.ReferencesOnly; currentAsmData.AdditionalInfo = currentAsmData.AdditionalInfo + "\r\nProcessorArchitecture mismatch"; } _parentsStack.Push(currentAsmData.AssemblyFullName); _cache.Add(analyzedAssembly.FullName, currentAsmData); foreach (System.Reflection.AssemblyName n in asm.GetReferencedAssemblies()) { this.AnalyzeAssembly(n, currentAsmData, domain, throwWhenMissing); } _parentsStack.Pop(); if (!System.IO.File.Exists(currentAsmData.Path)) { return; } } if (throwWhenMissing && !gacAssemblySet) { throw new Exception("returning from analysis"); } }