//stripped down version of: https://github.com/Keboo/AutoDI/blob/master/AutoDI.Build/AssemblyRewriteTask.cs private static Stream GetSymbolInformation(string assemblyFile, out ISymbolReaderProvider symbolReaderProvider, out ISymbolWriterProvider symbolWriterProvider) { string pdbPath = FindPdbPath(); if (pdbPath != null) { 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)); } symbolReaderProvider = null; symbolWriterProvider = null; return(null); string FindPdbPath() { string path = Path.ChangeExtension(assemblyFile, "pdb"); if (File.Exists(path)) { return(path); } return(null); } }
public void ProcessAssemblyAndSave(string rewrittenAssemblyPath) { var rewrittenAssembly = ProcessAssembly(); logger.Progress($"Saving assembly '{rewrittenAssembly.FullName}' to '{rewrittenAssemblyPath}'."); try { var symbolWriterProvider = new PdbWriterProvider(); var writerParameters = new WriterParameters() { WriteSymbols = true, SymbolWriterProvider = symbolWriterProvider }; rewrittenAssembly.Write(rewrittenAssemblyPath, new WriterParameters() { WriteSymbols = true }); } catch (Exception e) { throw new InvalidOperationException($"Error while saving assembly '{rewrittenAssemblyPath}'.", e); } logger.Progress("Saving assembly done."); }
static ModuleDefinition RoundtripModule(ModuleDefinition module, RoundtripType roundtripType) { if (roundtripType == RoundtripType.None) { return(module); } var file = Path.Combine(Path.GetTempPath(), "TestILProcessor.dll"); if (File.Exists(file)) { File.Delete(file); } ISymbolWriterProvider symbolWriterProvider; switch (roundtripType) { case RoundtripType.Pdb when Platform.HasNativePdbSupport: symbolWriterProvider = new PdbWriterProvider(); break; case RoundtripType.PortablePdb: default: symbolWriterProvider = new PortablePdbWriterProvider(); break; } module.Write(file, new WriterParameters { SymbolWriterProvider = symbolWriterProvider, }); module.Dispose(); ISymbolReaderProvider symbolReaderProvider; switch (roundtripType) { case RoundtripType.Pdb when Platform.HasNativePdbSupport: symbolReaderProvider = new PdbReaderProvider(); break; case RoundtripType.PortablePdb: default: symbolReaderProvider = new PortablePdbReaderProvider(); break; } return(ModuleDefinition.ReadModule(file, new ReaderParameters { SymbolReaderProvider = symbolReaderProvider, InMemory = true })); }
private WriterParameters CreateDefaultWriterParameters(string pdbPath = null) { var writerParameters = new WriterParameters(); if (!string.IsNullOrEmpty(pdbPath)) { var pdbWriterProvider = new PdbWriterProvider(); writerParameters.SymbolWriterProvider = pdbWriterProvider; writerParameters.WriteSymbols = true; } return(writerParameters); }
/// <summary> /// /// </summary> /// <param name="assemblyPath"></param> /// <param name="currentPath"></param> /// <param name="savePath"></param> /// <returns></returns> public static bool BuildToFile(string assemblyPath, string currentPath, string savePath = null) { bool setSuccess = false; if (string.IsNullOrEmpty(savePath)) { savePath = assemblyPath; } string pdbFile = Path.ChangeExtension(assemblyPath, "pdb"); PdbReaderProvider readerProvider = null; PdbWriterProvider writerProvider = null; bool debug = false; if (File.Exists(pdbFile)) { debug = true; readerProvider = new PdbReaderProvider(); writerProvider = new PdbWriterProvider(); } //huhu modify reason: Support for model debugging. var ass = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters { SymbolReaderProvider = readerProvider, ReadSymbols = debug }); BaseAssemblyResolver resolver = ass.MainModule.AssemblyResolver as BaseAssemblyResolver; if (resolver != null) { resolver.AddSearchDirectory(currentPath); } foreach (TypeDefinition type in ass.MainModule.GetTypes()) { if (type.IsEnum) { continue; } setSuccess = ProcessEntityType(type, setSuccess, currentPath); } //modify reason: no model. ass.Write(savePath, new WriterParameters { SymbolWriterProvider = writerProvider, WriteSymbols = debug }); return(true); }
/// <summary> /// /// </summary> /// <param name="assemblyPath"></param> /// <param name="outputAssembly"></param> /// <returns></returns> public static bool BuildToStream(string assemblyPath, out Stream outputAssembly) { bool setSuccess = false; string currentPath = Path.GetDirectoryName(assemblyPath); outputAssembly = new MemoryStream(); using (Stream stream = ReadAssembly(assemblyPath)) { string pdbFile = Path.ChangeExtension(assemblyPath, "pdb"); PdbReaderProvider readerProvider = null; PdbWriterProvider writerProvider = null; bool debug = false; if (File.Exists(pdbFile)) { debug = true; readerProvider = new PdbReaderProvider(); writerProvider = new PdbWriterProvider(); } var ass = AssemblyDefinition.ReadAssembly(stream, new ReaderParameters { SymbolReaderProvider = readerProvider, ReadSymbols = debug }); foreach (TypeDefinition type in ass.MainModule.GetTypes()) { if (type.IsEnum) { continue; } setSuccess = ProcessEntityType(type, setSuccess, currentPath); } if (setSuccess) { ass.Write(outputAssembly, new WriterParameters { SymbolWriterProvider = writerProvider, WriteSymbols = debug }); return(true); } } return(false); }
/// <summary> /// /// </summary> /// <param name="assemblyPath"></param> /// <param name="currentPath"></param> /// <param name="savePath"></param> /// <returns></returns> public static bool BuildToFile(string assemblyPath, string currentPath, string savePath = null) { bool setSuccess = false; if (string.IsNullOrEmpty(savePath)) { savePath = assemblyPath; } string pdbFile = Path.ChangeExtension(assemblyPath, "pdb"); PdbReaderProvider readerProvider = null; PdbWriterProvider writerProvider = null; bool debug = false; if (File.Exists(pdbFile)) { debug = true; readerProvider = new PdbReaderProvider(); writerProvider = new PdbWriterProvider(); } //huhu modify reason: Support for model debugging. var ass = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters { SymbolReaderProvider = readerProvider, ReadSymbols = debug }); var types = ass.MainModule.Types.Where(p => !p.IsEnum).ToList(); foreach (TypeDefinition type in types) { setSuccess = ProcessEntityType(type, setSuccess, currentPath); } //modify reason: no model. ass.Write(savePath, new WriterParameters { SymbolWriterProvider = writerProvider, WriteSymbols = debug }); return(true); }
public CecilMigrationResult Migrate(string source, string destination) { if (string.IsNullOrWhiteSpace(source)) { throw new ArgumentException($"Invalid source assembly path specified: '{source}'.", nameof(source)); } if (string.IsNullOrWhiteSpace(destination)) { throw new ArgumentException($"Invalid destination assembly path specified: '{destination}'.", nameof(destination)); } if (!File.Exists(source)) { throw new FileNotFoundException($"Source assembly does not exist: '{source}'.", source); } var pdbPath = Path.ChangeExtension(source, "pdb"); var destPdbPath = Path.ChangeExtension(destination, "pdb"); var tempDllPath = Path.ChangeExtension(destination, "temp.dll"); var tempPdbPath = Path.ChangeExtension(destination, "temp.pdb"); var hasPdb = File.Exists(pdbPath) && EnablePdbSupport; var result = CecilMigrationResult.Skipped; using (var resolver = new DefaultAssemblyResolver()) { resolver.AddSearchDirectory(Path.GetDirectoryName(source)); reset: var readerParams = new ReaderParameters { ReadSymbols = hasPdb, AssemblyResolver = resolver, }; var requiresSave = false; try { using (var assembly = AssemblyDefinition.ReadAssembly(source, readerParams)) { LogVerboseMessage($"Processing assembly '{source}'..."); if (!hasPdb) { LogVerboseMessage($" No debug symbols found for the assembly."); } result = MigrateAssembly(assembly); requiresSave = result.HasFlag(CecilMigrationResult.ContainedSupport) || result.HasFlag(CecilMigrationResult.ContainedJni) || result.HasFlag(CecilMigrationResult.ContainedJavaArtifacts); var dir = Path.GetDirectoryName(destination); if (!string.IsNullOrWhiteSpace(dir) && !Directory.Exists(dir)) { Directory.CreateDirectory(dir); } if (requiresSave) { Stream symbolStream = null; PdbWriterProvider symbolWriter = null; if (hasPdb) { symbolStream = File.Create(tempPdbPath); symbolWriter = new PdbWriterProvider(); } try { assembly.Write(tempDllPath, new WriterParameters { WriteSymbols = hasPdb, SymbolStream = symbolStream, SymbolWriterProvider = symbolWriter }); } finally { symbolStream?.Dispose(); } LogMessage($"Migrated assembly to '{destination}'."); } else { LogVerboseMessage($"Skipped assembly '{source}' due to lack of support types."); if (!source.Equals(destination, StringComparison.OrdinalIgnoreCase)) { LogVerboseMessage($"Copying source assembly '{source}' to '{destination}'."); File.Copy(source, destination, true); if (hasPdb) { File.Copy(pdbPath, destPdbPath, true); } } } } } catch (Mono.Cecil.Cil.SymbolsNotMatchingException) { LogMessage($"Symbols were found but are not matching the assembly({source})"); hasPdb = false; goto reset; } if (requiresSave) { if (File.Exists(tempDllPath)) { File.Copy(tempDllPath, destination, true); File.Delete(tempDllPath); } if (File.Exists(tempPdbPath)) { File.Copy(tempPdbPath, destPdbPath, true); File.Delete(tempPdbPath); } } } return(result); }
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); }