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); }