Esempio n. 1
0
        //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);
            }
        }
Esempio n. 2
0
        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.");
        }
Esempio n. 3
0
        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
            }));
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        /// <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);
        }
Esempio n. 6
0
        /// <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);
        }
Esempio n. 7
0
        /// <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);
        }
Esempio n. 9
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);
            }
        }
Esempio n. 10
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);
        }