Beispiel #1
0
        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);
                }
            }
        }
Beispiel #2
0
        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));
             *                      }*/
        }
Beispiel #5
0
        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);
            }
        }
Beispiel #6
0
        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);
        }