public static void SaveAssembly(AssemblyDefinition assembly, string destination) { bool symbols = assembly.MainModule.HasSymbols; // re-write symbols, if available, so the new tokens will match assembly.Write(destination, new WriterParameters() { WriteSymbols = symbols }); if (symbols) { // re-load symbols (cecil will dispose MdbReader and will crash later if we need to save again) var provider = new MdbReaderProvider(); assembly.MainModule.ReadSymbols(provider.GetSymbolReader(assembly.MainModule, destination)); } else { // if we're not saving the symbols then we must not leave stale/old files to be used by other tools string dest_mdb = destination + ".mdb"; if (File.Exists(dest_mdb)) { File.Delete(dest_mdb); } } }
private ISymbolReader ResolveSymbolReader() { string symbolLocation = null; string pdbLocation = Path.ChangeExtension(AssemblyLocation, "pdb"); string mdbLocation = AssemblyLocation + ".mdb"; ISymbolReaderProvider provider = null; if (File.Exists(pdbLocation)) { symbolLocation = pdbLocation; provider = new PdbReaderProvider(); } else if (File.Exists(mdbLocation)) { symbolLocation = AssemblyLocation; provider = new MdbReaderProvider(); } if (provider == null) { return(null); } var reader = provider.GetSymbolReader(Definition, symbolLocation); return(reader); }
public static void SaveAssembly(AssemblyDefinition assembly, string destination) { var main = assembly.MainModule; bool symbols = main.HasSymbols; if (symbols) { var provider = new MdbReaderProvider(); main.ReadSymbols(provider.GetSymbolReader(main, main.FileName)); } var wp = new WriterParameters() { WriteSymbols = symbols }; // re-write symbols, if available, so the new tokens will match assembly.Write(destination, wp); if (!symbols) { // if we're not saving the symbols then we must not leave stale/old files to be used by other tools string dest_mdb = destination + ".mdb"; if (File.Exists(dest_mdb)) { File.Delete(dest_mdb); } } }
public void LoadFrom(FilePath assemblyPath) { FileName = assemblyPath; var tid = Runtime.SystemAssemblyService.GetTargetFrameworkForAssembly(Runtime.SystemAssemblyService.DefaultRuntime, assemblyPath); if (tid != null) { targetFramework = Runtime.SystemAssemblyService.GetTargetFramework(tid); } AssemblyDefinition adef = AssemblyDefinition.ReadAssembly(assemblyPath); MdbReaderProvider mdbProvider = new MdbReaderProvider(); try { ISymbolReader reader = mdbProvider.GetSymbolReader(adef.MainModule, assemblyPath); adef.MainModule.ReadSymbols(reader); } catch { // Ignore } var files = new HashSet <FilePath> (); foreach (TypeDefinition type in adef.MainModule.Types) { foreach (MethodDefinition met in type.Methods) { if (met.HasBody && met.Body.Instructions != null && met.Body.Instructions.Count > 0) { SequencePoint sp = met.Body.Instructions[0].SequencePoint; if (sp != null) { files.Add(sp.Document.Url); } } } } FilePath rootPath = FilePath.Empty; foreach (FilePath file in files) { AddFile(file, BuildAction.Compile); if (rootPath.IsNullOrEmpty) { rootPath = file.ParentDirectory; } else if (!file.IsChildPathOf(rootPath)) { rootPath = FindCommonRoot(rootPath, file); } } if (!rootPath.IsNullOrEmpty) { BaseDirectory = rootPath; } /* * foreach (AssemblyNameReference aref in adef.MainModule.AssemblyReferences) { * if (aref.Name == "mscorlib") * continue; * string asm = assemblyPath.ParentDirectory.Combine (aref.Name); * if (File.Exists (asm + ".dll")) * References.Add (new ProjectReference (ReferenceType.Assembly, asm + ".dll")); * else if (File.Exists (asm + ".exe")) * References.Add (new ProjectReference (ReferenceType.Assembly, asm + ".exe")); * else * References.Add (new ProjectReference (ReferenceType.Package, aref.FullName)); * }*/ }
private Stream GetSymbolInformation(out ISymbolReaderProvider symbolReaderProvider, out ISymbolWriterProvider symbolWriterProvider) { if (string.Equals("none", DebugType, StringComparison.OrdinalIgnoreCase)) { Logger.Info("No symbols"); symbolReaderProvider = null; symbolWriterProvider = null; return(null); } if (string.Equals("embedded", DebugType, StringComparison.OrdinalIgnoreCase)) { Logger.Info("Using embedded symbols"); symbolReaderProvider = new EmbeddedPortablePdbReaderProvider(); symbolWriterProvider = new EmbeddedPortablePdbWriterProvider(); return(null); } string pdbPath = FindPdbPath(); string mdbPath = FindMdbPath(); if (pdbPath != null && mdbPath != null) { if (File.GetLastWriteTimeUtc(pdbPath) >= File.GetLastWriteTimeUtc(mdbPath)) { mdbPath = null; Logger.Debug("Found mdb and pdb debug symbols. Selected pdb (newer).", DebugLogLevel.Verbose); } else { pdbPath = null; Logger.Debug("Found mdb and pdb debug symbols. Selected mdb (newer).", DebugLogLevel.Verbose); } } if (pdbPath != null) { Logger.Info($"Using symbol file {pdbPath}"); symbolReaderProvider = new PdbReaderProvider(); symbolWriterProvider = new PdbWriterProvider(); string tempPath = pdbPath + ".tmp"; File.Copy(pdbPath, tempPath, true); return(new FileStream(tempPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); } else if (mdbPath != null) { Logger.Info($"Using symbol file {mdbPath}"); symbolReaderProvider = new MdbReaderProvider(); symbolWriterProvider = new MdbWriterProvider(); string tempPath = mdbPath + ".tmp"; File.Copy(mdbPath, tempPath, true); return(new FileStream(tempPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); } symbolReaderProvider = null; symbolWriterProvider = null; return(null); string FindPdbPath() { // because UWP use a wacky convention for symbols string path = Path.ChangeExtension(AssemblyFile, "compile.pdb"); if (File.Exists(path)) { Logger.Debug($"Found debug symbols at '{path}'.", DebugLogLevel.Verbose); return(path); } path = Path.ChangeExtension(AssemblyFile, "pdb"); if (File.Exists(path)) { Logger.Debug($"Found debug symbols at '{path}'.", DebugLogLevel.Verbose); return(path); } return(null); } string FindMdbPath() { string path = AssemblyFile + ".mdb"; if (File.Exists(path)) { Logger.Debug($"Found debug symbols at '{path}'.", DebugLogLevel.Verbose); return(path); } return(null); } }
public bool ProcessFile(string sourceFile, string targetFile = "") { bool result = false; if (string.IsNullOrEmpty(targetFile)) { targetFile = sourceFile; } Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); try { var resolver = new DefaultAssemblyResolver(); resolver.AddSearchDirectory(GetAssemblyDirectoryFromType(typeof(Resource))); var parameters = new ReaderParameters { AssemblyResolver = resolver }; Assembly = AssemblyDefinition.ReadAssembly(sourceFile, parameters); Log.LogMessage("------ Begin Task: ImplementRdfMapping [{0}]", Assembly.Name); bool assemblyModified = false; // Iterate over all types in the main assembly. foreach (TypeDefinition type in Assembly.MainModule.Types) { // In the following we need to seperate between properties which have the following attribute combinations: // - PropertyAttribute with PropertyChangedAttribute // - PropertyAttribute without PropertyChangedAttribute // - PropertyChangedAttribute only HashSet <PropertyDefinition> mapping = type.GetPropertiesWithAttribute <RdfPropertyAttribute>().ToHashSet(); HashSet <PropertyDefinition> notifying = type.GetPropertiesWithAttribute <NotifyPropertyChangedAttribute>().ToHashSet(); // Implement the GetTypes()-method for the given type. if (mapping.Any() || type.TryGetCustomAttribute <RdfClassAttribute>().Any()) { ImplementRdfClassTask implementClass = new ImplementRdfClassTask(this, type); // RDF types _must_ be implemented for classes with mapped properties. assemblyModified = implementClass.Execute(); } // Properties which do not raise the PropertyChanged-event can be implemented using minimal IL code. if (mapping.Any()) { var implementProperty = new ImplementRdfPropertyTask(this, type); foreach (PropertyDefinition p in mapping.Except(notifying).Where(implementProperty.CanExecute)) { assemblyModified = implementProperty.Execute(p); } } // Properties which raise the PropertyChanged-event may also have the RdfProperty attribute. if (notifying.Any()) { var implementPropertyChanged = new ImplementNotifyPropertyChangedTask(this, type); foreach (PropertyDefinition p in notifying.Where(implementPropertyChanged.CanExecute)) { implementPropertyChanged.IsMappedProperty = mapping.Contains(p); assemblyModified = implementPropertyChanged.Execute(p); } } } if (assemblyModified) { if (WriteSymbols) { // Use the correct debug symbol reader and writer on Mono and .NET if (Type.GetType("Mono.Runtime") != null) { using (ISymbolReader symbolReader = new MdbReaderProvider().GetSymbolReader(Assembly.MainModule, sourceFile)) { ISymbolWriterProvider symbolWriter = new MdbWriterProvider(); WriteSymbolsToAssembly(targetFile, symbolReader, symbolWriter); } } else { using (ISymbolReader symbolReader = new PdbReaderProvider().GetSymbolReader(Assembly.MainModule, sourceFile)) { ISymbolWriterProvider symbolWriter = new PdbWriterProvider(); WriteSymbolsToAssembly(targetFile, symbolReader, symbolWriter); } } } else { Assembly.Write(targetFile, new WriterParameters { WriteSymbols = false }); } } result = true; } catch (Exception ex) { Log.LogError(ex.ToString()); result = false; } stopwatch.Stop(); Log.LogMessage("------ End Task: ImplementRdfMapping [Total time: {0}s]", stopwatch.Elapsed.TotalSeconds); return(result); }