public override bool Execute()
        {
            foreach (var assemblySpec in Assemblies)
            {
                var assembly = assemblySpec.ItemSpec;
                if (string.IsNullOrEmpty(assembly) || !File.Exists(assembly))
                {
                    continue;
                }

                Log.LogMessage($"Redirecting types for {assembly}...");

                var tempFile = assembly + ".temp.dll";

                using var resolver = new AssemblyResolver();
                foreach (var reference in References)
                {
                    var r = reference.ItemSpec;
                    if (string.IsNullOrEmpty(r) || !File.Exists(r))
                    {
                        continue;
                    }

                    resolver.AddAssembly(r);
                }

                var readerParams = new ReaderParameters
                {
                    ReadSymbols      = true,
                    ReadWrite        = true,
                    AssemblyResolver = resolver,
                };
                using (var assemblyDefinition = AssemblyDefinition.ReadAssembly(assembly, readerParams))
                {
                    RedirectTypes(assemblyDefinition, assembly);

                    var writerParams = new WriterParameters
                    {
                        WriteSymbols         = true,
                        SymbolWriterProvider = new PortablePdbWriterProvider(),
                    };
                    assemblyDefinition.Write(writerParams);
                }

                // remove any .dll.mdb that we don't want
                TryDelete(assembly + ".mdb");
            }

            return(true);
        }
Example #2
0
        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(destination, "pdb");
            var mdbPath = destination + ".mdb";

            // copy the files to the dest to start off
            if (CopyFile(source, destination))
            {
                LogVerboseMessage($"Copying source assembly '{source}' to '{destination}'.");

                CopyFile(Path.ChangeExtension(source, "pdb"), pdbPath);
                CopyFile(source + ".mdb", mdbPath);
            }

            var hasSymbols = File.Exists(pdbPath) || File.Exists(mdbPath);

            // start the migration
            var result       = CecilMigrationResult.Skipped;
            var requiresSave = false;

            using (var resolver = new AssemblyResolver())
            {
                if (References?.Count > 0)
                {
                    var refs = References
                               .Where(r => Path.GetFileName(r) != Path.GetFileName(destination))
                               .ToList();
                    foreach (var reference in refs)
                    {
                        resolver.AddAssembly(reference);
                    }
                }

                var readerParams = new ReaderParameters
                {
                    ReadSymbols      = hasSymbols,
                    ReadWrite        = true,
                    AssemblyResolver = resolver,
                };

                LogVerboseMessage($"Processing assembly '{source}'...");
                using (var assembly = AssemblyDefinition.ReadAssembly(destination, readerParams))
                {
                    if (!hasSymbols)
                    {
                        LogVerboseMessage($"  No debug symbols found for the assembly.");
                    }

                    result = MigrateAssembly(assembly);

                    requiresSave =
                        result.HasFlag(CecilMigrationResult.ContainedSupport) ||
                        result.HasFlag(CecilMigrationResult.ContainedJni) ||
                        result.HasFlag(CecilMigrationResult.ContainedJavaArtifacts);

                    if (requiresSave)
                    {
                        assembly.Write(new WriterParameters
                        {
                            WriteSymbols         = hasSymbols,
                            SymbolWriterProvider = hasSymbols ? new PortablePdbWriterProvider() : null,
                        });

                        LogMessage($"Migrated assembly to '{destination}'.");
                    }
                    else
                    {
                        LogVerboseMessage($"Skipped assembly '{source}' due to lack of support types.");
                    }
                }
            }

            if (requiresSave)
            {
                // remove .dll.mdb as that is not supported
                if (File.Exists(mdbPath))
                {
                    File.Delete(mdbPath);
                }
            }

            return(result);
        }