Ejemplo n.º 1
0
        public ILRepack(RepackOptions options, ILogger logger)
        {
            Options = options;
            Logger  = logger;

            _repackImporter = new RepackImporter(Logger, Options, this, _aspOffsets);
        }
Ejemplo n.º 2
0
 public static void DoRepackForCmd(IEnumerable<string> args)
 {
     var repackOptions = new RepackOptions(args.Concat(new[] { "/log" }));
     var repack = new ILRepacking.ILRepack(repackOptions);
     repack.Repack();
     ReloadAndCheckReferences(repackOptions);
 }
Ejemplo n.º 3
0
        public RepackLogger(RepackOptions options)
        {
            ShouldLogVerbose = options.LogVerbose;

            if (Open(options.LogFile))
            {
                options.Log = true;
            }
        }
Ejemplo n.º 4
0
 private static void ReloadAndCheckReferences(RepackOptions repackOptions)
 {
     var outputFile = AssemblyDefinition.ReadAssembly(repackOptions.OutputFile, new ReaderParameters(ReadingMode.Immediate));
     var mergedFiles = repackOptions.ResolveFiles().Select(f => AssemblyDefinition.ReadAssembly(f, new ReaderParameters(ReadingMode.Deferred)));
     foreach (var a in outputFile.MainModule.AssemblyReferences.Where(x => mergedFiles.Any(y => repackOptions.KeepOtherVersionReferences ? x.FullName == y.FullName : x.Name == y.Name.Name)))
     {
         Assert.Fail($"Merged assembly retains a reference to one (or more) of the merged files: ${a.FullName}");
     }
 }
Ejemplo n.º 5
0
        public ILRepack(RepackOptions options, ILogger logger)
        {
            Options = options;
            Logger  = logger;

            logger.ShouldLogVerbose = options.LogVerbose;

            _repackImporter = new RepackImporter(Logger, Options, this, _aspOffsets);
        }
Ejemplo n.º 6
0
        public ILRepack(RepackOptions options, ILogger logger)
        {
            Options = options;
            Logger = logger;

            logger.ShouldLogVerbose = options.LogVerbose;

            _repackImporter = new RepackImporter(Logger, Options, this, _aspOffsets);
        }
Ejemplo n.º 7
0
 public RepackImporter(
     ILogger logger,
     RepackOptions options,
     IRepackContext repackContext,
     Dictionary <AssemblyDefinition, int> aspOffsets)
 {
     _logger        = logger;
     _options       = options;
     _repackContext = repackContext;
     _aspOffsets    = aspOffsets;
 }
Ejemplo n.º 8
0
        static int Main(string[] args)
        {
            ICommandLine  commandLine = new CommandLine(args);
            ILogger       logger      = new RepackLogger();
            IFile         file        = new FileWrapper();
            RepackOptions options     = new RepackOptions(commandLine, logger, file);
            int           returnCode  = -1;

            try
            {
                if (options.ShouldShowUsage())
                {
                    Usage();
                    Exit(2);
                }
                options.Parse();

                //TODO: Open the Logger before the parse
                if (logger.Open(options.LogFile))
                {
                    options.Log             = true;
                    logger.ShouldLogVerbose = options.LogVerbose;
                }

                ILRepack repack = new ILRepack(options, logger);
                repack.Repack();
                returnCode = 0;
            }
            catch (RepackOptions.InvalidTargetKindException e)
            {
                Console.WriteLine(e.Message);
                Usage();
                Exit(2);
            }
            catch (Exception e)
            {
                logger.Log(e);
                returnCode = 1;
            }
            finally
            {
                logger.Close();
                if (options.PauseBeforeExit)
                {
                    Console.WriteLine("Press Any Key To Continue");
                    Console.ReadKey(true);
                }
            }
            return(returnCode);
        }
Ejemplo n.º 9
0
        static int Main(string[] args)
        {
            RepackLogger logger = new RepackLogger();
            RepackOptions options = new RepackOptions(args);
            int returnCode = -1;
            try
            {
                if (options.ShouldShowUsage)
                {
                    Usage();
                    Exit(2);
                }
                logger.ShouldLogVerbose = options.LogVerbose;
                //TODO: Open the Logger before the parse
                if (logger.Open(options.LogFile))
                {
                    options.Log = true;
                }

                ILRepack repack = new ILRepack(options, logger);
                repack.Repack();
                returnCode = 0;
            }
            catch (RepackOptions.InvalidTargetKindException e)
            {
                Console.WriteLine(e.Message);
                Usage();
                Exit(2);
            }
            catch (Exception e)
            {
                logger.Log(e);
                returnCode = 1;
            }
            finally
            {
                logger.Close();
                if (options.PauseBeforeExit)
                {
                    Console.WriteLine("Press Any Key To Continue");
                    Console.ReadKey(true);
                }
            }
            return returnCode;
        }
Ejemplo n.º 10
0
        static int Main(string[] args)
        {
            RepackOptions options    = new RepackOptions(args);
            var           logger     = new RepackLogger(options);
            int           returnCode = -1;

            try
            {
                if (options.ShouldShowUsage)
                {
                    Usage();
                    Exit(2);
                }

                ILRepack repack = new ILRepack(options, logger);
                repack.Repack();
                repack.Dispose();
                returnCode = 0;
            }
            catch (RepackOptions.InvalidTargetKindException e)
            {
                Console.WriteLine(e.Message);
                Usage();
                Exit(2);
            }
            catch (Exception e)
            {
                logger.Log(e);
                returnCode = 1;
            }
            finally
            {
                logger.Dispose();
                if (options.PauseBeforeExit)
                {
                    Console.WriteLine("Press Any Key To Continue");
                    Console.ReadKey(true);
                }
            }
            return(returnCode);
        }
Ejemplo n.º 11
0
 public ILRepack(RepackOptions options, ILogger logger)
 {
     Options = options;
     Logger = logger;
     _repackImporter = new RepackImporter(Logger, Options, this, _aspOffsets);
 }
Ejemplo n.º 12
0
 public ILRepack(RepackOptions options)
     : this(options, new RepackLogger())
 {
 }
Ejemplo n.º 13
0
 public ILRepack(RepackOptions options)
     : this(options, new RepackLogger())
 {
 }
Ejemplo n.º 14
0
 void Parse()
 {
     options = new RepackOptions(commandLine.Object, file.Object);
 }
Ejemplo n.º 15
0
        /// <summary>
        /// Merges the proxy and the target assemblies.
        /// </summary>
        /// <param name="outputPath">The path of the resulting assembly.</param>
        private void Merge(string outputPath)
        {
            Contract.Requires(outputPath != null);

            var options = new RepackOptions
            {
                InputAssemblies = new[] { this.Pair.Target.FilePath, this.Pair.Proxy.FilePath },
                OutputFile = outputPath,
                TargetKind = ILRepack.Kind.Dll,
                SearchDirectories = new[] { this.Pair.Target.FilePath, this.Pair.Proxy.FilePath }.Select(Path.GetDirectoryName),
                KeyFile = Path.Combine(this.CurrentDirectoryPath, "MockEverything.snk"),
            };

            // The `Log` property of `RepackOptions` being gracefully ignored by the library (see ILRepack/RepackLogger.cs, l. 16), the only way to get rid of the logging is to create a logger which does nothing.
            new ILRepack(options, new NullLogger()).Repack();
        }
Ejemplo n.º 16
0
        public static AssemblyDefinition GenerateRoslynAssembly(CustomAssemblyResolver assemblyResolver, AssemblyDefinition assembly, string serializationAssemblyLocation, string signKeyFile, List <string> references, List <AssemblyDefinition> memoryReferences, TextWriter log, IEnumerable <SourceCode> sourceCodes)
        {
            var sourceFolder = Path.GetDirectoryName(serializationAssemblyLocation);
            var syntaxTrees  = sourceCodes.Select(x =>
            {
                // It has a name, let's save it as a file
                string sourcePath = null;
                if (x.Name != null)
                {
                    sourcePath = Path.Combine(sourceFolder, $"{x.Name}.cs");
                    File.WriteAllText(sourcePath, x.Code);
                }

                var result = CSharpSyntaxTree.ParseText(x.Code, null, sourcePath, Encoding.UTF8);

                return(result);
            }).ToArray();

            var compilerOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true, assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default);

            // Sign the serialization assembly the same way the source was signed
            // TODO: Transmit over command line
            if (assembly.Name.HasPublicKey)
            {
                // TODO: If delay signed, we could actually extract the public key and apply it ourself maybe?
                if (signKeyFile == null)
                {
                    throw new InvalidOperationException("Generating serialization code for signed assembly, but no key was specified.");
                }

                compilerOptions = compilerOptions.WithCryptoKeyFile(signKeyFile).WithStrongNameProvider(new DesktopStrongNameProvider());
                if ((assembly.MainModule.Attributes & ModuleAttributes.StrongNameSigned) != ModuleAttributes.StrongNameSigned)
                {
                    // Delay signed
                    compilerOptions = compilerOptions.WithDelaySign(true);
                }
            }

            // Add references (files and in-memory PE data)
            var metadataReferences = new List <MetadataReference>();

            foreach (var reference in assemblyResolver.References)
            {
                metadataReferences.Add(MetadataReference.CreateFromFile(reference));
            }

            foreach (var reference in memoryReferences)
            {
                metadataReferences.Add(CreateMetadataReference(assemblyResolver, reference));
            }

            // typeof(Dictionary<,>)
            // Special case for 4.5: Because Dictionary<,> is forwarded, we need to add a reference to the actual assembly
            var mscorlibAssembly = CecilExtensions.FindCorlibAssembly(assembly);

            metadataReferences.Add(CreateMetadataReference(assemblyResolver, mscorlibAssembly));
            var collectionAssembly = CecilExtensions.FindCollectionsAssembly(assembly);

            metadataReferences.Add(CreateMetadataReference(assemblyResolver, collectionAssembly));

            // Open file currently being processed using FileShare.ReadWrite
            using (var stream = File.Open(assembly.MainModule.FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                metadataReferences.Add(MetadataReference.CreateFromStream(stream, filePath: assembly.MainModule.FileName));

            // In case SiliconStudio.Core was not referenced, let's add it.
            if (assembly.Name.Name != "SiliconStudio.Core" && !references.Any(x => string.Compare(Path.GetFileNameWithoutExtension(x), "SiliconStudio.Core", StringComparison.OrdinalIgnoreCase) == 0))
            {
                metadataReferences.Add(CreateMetadataReference(assemblyResolver, assemblyResolver.Resolve(new AssemblyNameReference("SiliconStudio.Core", null))));
            }

            // Create roslyn compilation object
            var assemblyName = assembly.Name.Name + ".Serializers";
            var compilation  = CSharpCompilation.Create(assemblyName, syntaxTrees, metadataReferences, compilerOptions);

            // Do the actual compilation, and check errors
            using (var peStream = new FileStream(serializationAssemblyLocation, FileMode.Create, FileAccess.Write))
                using (var pdbStream = new FileStream(Path.ChangeExtension(serializationAssemblyLocation, ".pdb"), FileMode.Create, FileAccess.Write))
                {
                    var compilationResult = compilation.Emit(peStream, pdbStream);

                    if (!compilationResult.Success)
                    {
                        var errors = new StringBuilder();
                        errors.AppendLine(string.Format("Serialization assembly compilation: {0} error(s)", compilationResult.Diagnostics.Count(x => x.Severity >= DiagnosticSeverity.Error)));
                        foreach (var error in compilationResult.Diagnostics)
                        {
                            if (error.Severity >= DiagnosticSeverity.Warning)
                            {
                                errors.AppendLine(error.ToString());
                            }
                        }
                        throw new InvalidOperationException(errors.ToString());
                    }
                }

            // Make sure every instruction in the primary assembly has offset up to date
            // Ideally, we should do it manually only on method whose instructions changed so far
            foreach (var type in assembly.MainModule.Types)
            {
                GenerateOffsetForMethodsOfType(type);
            }

            var repackOptions = new ILRepacking.RepackOptions(new string[0])
            {
                OutputFile     = assembly.MainModule.FileName,
                DebugInfo      = true,
                CopyAttributes = true,
                AllowMultipleAssemblyLevelAttributes = true,
                XmlDocumentation  = false,
                NoRepackRes       = true,
                InputAssemblies   = new[] { serializationAssemblyLocation },
                SearchDirectories = new string[0],
            };

            // Run ILMerge
            var merge = new ILRepacking.ILRepack(repackOptions)
            {
                GlobalAssemblyResolver    = new RepackAssemblyResolverAdapter(assemblyResolver),
                PrimaryAssemblyDefinition = assembly,
                MemoryOnly = true,
                //KeepFirstOfMultipleAssemblyLevelAttributes = true,
                //Log = true,
                //LogFile = "ilmerge.log",
            };

            try
            {
                var consoleWriter = Console.Out;
                Console.SetOut(TextWriter.Null);

                try
                {
                    merge.Repack();
                }
                finally
                {
                    Console.SetOut(consoleWriter);
                }
            }
            catch (Exception)
            {
                log.WriteLine($"Error while ILRepacking {assembly.Name.Name}");
                throw;
            }

            // Copy name
            merge.TargetAssemblyDefinition.Name.Name    = assembly.Name.Name;
            merge.TargetAssemblyDefinition.Name.Version = assembly.Name.Version;

            // Copy assembly characterics. This is necessary especially when targeting a windows app
            merge.TargetAssemblyMainModule.Characteristics = assembly.MainModule.Characteristics;

            // Add assembly signing info
            if (assembly.Name.HasPublicKey)
            {
                merge.TargetAssemblyDefinition.Name.PublicKey      = assembly.Name.PublicKey;
                merge.TargetAssemblyDefinition.Name.PublicKeyToken = assembly.Name.PublicKeyToken;
                merge.TargetAssemblyDefinition.Name.Attributes    |= AssemblyAttributes.PublicKey;
                if ((assembly.MainModule.Attributes & ModuleAttributes.StrongNameSigned) == ModuleAttributes.StrongNameSigned)
                {
                    merge.TargetAssemblyMainModule.Attributes |= ModuleAttributes.StrongNameSigned;
                }
            }

            // Dispose old assembly
            assembly.Dispose();

            try
            {
                // Delete serializer dll
                File.Delete(serializationAssemblyLocation);

                var serializationAssemblyPdbFilePath = Path.ChangeExtension(serializationAssemblyLocation, "pdb");
                if (File.Exists(serializationAssemblyPdbFilePath))
                {
                    File.Delete(serializationAssemblyPdbFilePath);
                }
            }
            catch (IOException)
            {
                // Mute IOException
            }

            return(merge.TargetAssemblyDefinition);
        }
Ejemplo n.º 17
0
        private static void ProcessRedirects(DataSet set, HashSet <string> mergedAssemblies, HashSet <string> redirectedAssemblies, RepackOptions repackOptions)
        {
            if (repackOptions.KeepOtherVersionReferences)
            {
                return;
            }

            var table          = set.Tables["assemblyIdentity"];
            var parentRelation = table?.ParentRelations["dependentAssembly_assemblyIdentity"];

            if (parentRelation == null)
            {
                return;
            }

            var nameCol = table.Columns["name"];

            foreach (var row in table.Select())
            {
                var name = row[nameCol] as string;
                if (name == null)
                {
                    continue;
                }
                var parent = row.GetParentRow(parentRelation);
                if (!mergedAssemblies.Contains(name) && !redirectedAssemblies.Contains(name))
                {
                    redirectedAssemblies.Add(name);
                    continue;
                }
                parent.Delete();
            }
            set.AcceptChanges();

            var bindingTable  = set.Tables["assemblyBinding"];
            var childRelation = bindingTable?.ChildRelations["assemblyBinding_dependentAssembly"];

            if (childRelation == null)
            {
                return;
            }

            foreach (var binding in bindingTable.Select())
            {
                var children = binding.GetChildRows(childRelation);
                if (children.Length == 0)
                {
                    binding.Delete();
                }
            }
            set.AcceptChanges();
        }