Beispiel #1
0
        /// <summary>
        /// The actual repacking process, called by main after parsing arguments.
        /// When referencing this assembly, call this after setting the merge properties.
        /// Skips SourceServerData step.
        /// </summary>
        public void Repack(ModuleDefinition primaryModuleDefinition, IList <ModuleDefinition> modulesToMerge)
        {
            // System.Diagnostics.Debugger.Launch();

            TargetAssemblyDefinition  = primaryModuleDefinition.Assembly;
            PrimaryAssemblyDefinition = primaryModuleDefinition.Assembly;
            MergedAssemblies          = new List <AssemblyDefinition>(modulesToMerge.Select(m => m.Assembly))
            {
                primaryModuleDefinition.Assembly
            };

            GlobalAssemblyResolver.RegisterAssemblies(MergedAssemblies);
            OtherAssemblies = new List <AssemblyDefinition>(modulesToMerge.Select(m => m.Assembly));

            _reflectionHelper = new ReflectionHelper(this);
            _platformFixer    = new PlatformFixer(this, PrimaryAssemblyMainModule.Runtime);
            _mappingHandler   = new MappingHandler();

            // set the main module attributes
            TargetAssemblyMainModule.Attributes = PrimaryAssemblyMainModule.Attributes;

            if (Options.Version != null)
            {
                TargetAssemblyDefinition.Name.Version = Options.Version;
            }

            _lineIndexer = new IKVMLineIndexer(this, Options.LineIndexation);

            List <IRepackStep> repackSteps = new List <IRepackStep>
            {
                new SigningStep(this, Options),
                new ReferencesRepackStep(Logger, this),
                new TypesRepackStep(Logger, this, _repackImporter, Options),
                new ResourcesRepackStep(Logger, this, Options),
                new AttributesRepackStep(Logger, this, _repackImporter, Options),
                new ReferencesFixStep(Logger, this, _repackImporter, Options),
                new XamlResourcePathPatcherStep(Logger, this)
            };

            foreach (var step in repackSteps)
            {
                step.Perform();
            }
        }
Beispiel #2
0
        public TypeDefinition Import(TypeDefinition type, Collection <TypeDefinition> col, bool internalize)
        {
            _logger.Verbose("- Importing " + type);

            TypeDefinition nt = _repackContext.TargetAssemblyMainModule.GetType(type.FullName);
            bool           justCreatedType = false;

            if (nt == null)
            {
                nt = CreateType(type, col, internalize, null);
                justCreatedType = true;
            }
            else if (DuplicateTypeAllowed(type))
            {
                _logger.Info("Merging " + type);
            }
            else if (!type.IsPublic || internalize)
            {
                // rename the type previously imported.
                // renaming the new one before import made Cecil throw an exception.
                string other = "<" + Guid.NewGuid() + ">" + nt.Name;
                _logger.Info("Renaming " + nt.FullName + " into " + other);
                nt.Name         = other;
                nt              = CreateType(type, col, internalize, null);
                justCreatedType = true;
            }
            else if (_options.UnionMerge)
            {
                _logger.Info("Merging " + type);
            }
            else
            {
                _logger.Error("Duplicate type " + type);
                throw new InvalidOperationException(
                          "Duplicate type " + type + " from " + type.Scope + ", was also present in " +
                          MappingHandler.GetScopeFullName(_repackContext.MappingHandler.GetOrigTypeScope <IMetadataScope>(nt)));
            }
            _repackContext.MappingHandler.StoreRemappedType(type, nt);

            // nested types first (are never internalized)
            foreach (TypeDefinition nested in type.NestedTypes)
            {
                Import(nested, nt.NestedTypes, false);
            }
            foreach (FieldDefinition field in type.Fields)
            {
                CloneTo(field, nt);
            }

            // methods before fields / events
            foreach (MethodDefinition meth in type.Methods)
            {
                CloneTo(meth, nt, justCreatedType);
            }

            foreach (EventDefinition evt in type.Events)
            {
                CloneTo(evt, nt, nt.Events);
            }
            foreach (PropertyDefinition prop in type.Properties)
            {
                CloneTo(prop, nt, nt.Properties);
            }
            return(nt);
        }
Beispiel #3
0
        /// <summary>
        /// The actual repacking process, called by main after parsing arguments.
        /// When referencing this assembly, call this after setting the merge properties.
        /// </summary>
        public void Repack()
        {
            Options.Validate();
            PrintRepackVersion();
            _reflectionHelper = new ReflectionHelper(this);
            ResolveSearchDirectories();

            // Read input assemblies only after all properties are set.
            ReadInputAssemblies();
            GlobalAssemblyResolver.RegisterAssemblies(MergedAssemblies);

            _platformFixer = new PlatformFixer(this, PrimaryAssemblyMainModule.Runtime);
            _mappingHandler = new MappingHandler();
            bool hadStrongName = PrimaryAssemblyDefinition.Name.HasPublicKey;

            ModuleKind kind = PrimaryAssemblyMainModule.Kind;
            if (Options.TargetKind.HasValue)
            {
                switch (Options.TargetKind.Value)
                {
                    case Kind.Dll: kind = ModuleKind.Dll; break;
                    case Kind.Exe: kind = ModuleKind.Console; break;
                    case Kind.WinExe: kind = ModuleKind.Windows; break;
                }
            }
            TargetRuntime runtime = ParseTargetPlatform();

            // change assembly's name to correspond to the file we create
            string mainModuleName = Path.GetFileNameWithoutExtension(Options.OutputFile);

            if (TargetAssemblyDefinition == null)
            {
                AssemblyNameDefinition asmName = Clone(PrimaryAssemblyDefinition.Name);
                asmName.Name = mainModuleName;
                TargetAssemblyDefinition = AssemblyDefinition.CreateAssembly(asmName, mainModuleName,
                    new ModuleParameters()
                    {
                        Kind = kind,
                        Architecture = PrimaryAssemblyMainModule.Architecture,
                        AssemblyResolver = GlobalAssemblyResolver,
                        Runtime = runtime
                    });
            }
            else
            {
                // TODO: does this work or is there more to do?
                TargetAssemblyMainModule.Kind = kind;
                TargetAssemblyMainModule.Runtime = runtime;

                TargetAssemblyDefinition.Name.Name = mainModuleName;
                TargetAssemblyMainModule.Name = mainModuleName;
            }
            // set the main module attributes
            TargetAssemblyMainModule.Attributes = PrimaryAssemblyMainModule.Attributes;
            TargetAssemblyMainModule.Win32ResourceDirectory = MergeWin32Resources(PrimaryAssemblyMainModule.Win32ResourceDirectory);

            if (Options.Version != null)
                TargetAssemblyDefinition.Name.Version = Options.Version;

            _lineIndexer = new IKVMLineIndexer(this, Options.LineIndexation);
            var signingStep = new SigningStep(this, Options);

            List<IRepackStep> repackSteps = new List<IRepackStep>
            {
                signingStep,
                new ReferencesRepackStep(Logger, this),
                new TypesRepackStep(Logger, this, _repackImporter, Options),
                new ResourcesRepackStep(Logger, this, Options),
                new AttributesRepackStep(Logger, this, _repackImporter, Options),
                new ReferencesFixStep(Logger, this, _repackImporter, Options),
                new XamlResourcePathPatcherStep(Logger, this)
            };

            foreach (var step in repackSteps)
            {
                step.Perform();
            }

            var parameters = new WriterParameters
            {
                StrongNameKeyPair = signingStep.KeyPair,
                WriteSymbols = Options.DebugInfo
            };
            // create output directory if it does not exist
            var outputDir = Path.GetDirectoryName(Options.OutputFile);
            if (!string.IsNullOrEmpty(outputDir) && !Directory.Exists(outputDir))
            {
                Logger.Info("Output directory does not exist. Creating output directory: " + outputDir);
                Directory.CreateDirectory(outputDir);
            }
            TargetAssemblyDefinition.Write(Options.OutputFile, parameters);
            Logger.Info("Writing output assembly to disk");
            // If this is an executable and we are on linux/osx we should copy file permissions from
            // the primary assembly
            if (Environment.OSVersion.Platform == PlatformID.MacOSX || Environment.OSVersion.Platform == PlatformID.Unix)
            {
                Stat stat;
                Logger.Info("Copying permissions from " + PrimaryAssemblyFile);
                Syscall.stat(PrimaryAssemblyFile, out stat);
                Syscall.chmod(Options.OutputFile, stat.st_mode);
            }
            if (hadStrongName && !TargetAssemblyDefinition.Name.HasPublicKey)
                Options.StrongNameLost = true;

            // nice to have, merge .config (assembly configuration file) & .xml (assembly documentation)
            ConfigMerger.Process(this);
            if (Options.XmlDocumentation)
                DocumentationMerger.Process(this);
        }
Beispiel #4
0
        /// <summary>
        /// The actual repacking process, called by main after parsing arguments.
        /// When referencing this assembly, call this after setting the merge properties.
        /// </summary>
        public void Repack()
        {
            Options.Validate();
            _reflectionHelper = new ReflectionHelper(this);
            ResolveSearchDirectories();

            // Read input assemblies only after all properties are set.
            ReadInputAssemblies();
            GlobalAssemblyResolver.RegisterAssemblies(MergedAssemblies);

            _platformFixer  = new PlatformFixer(PrimaryAssemblyMainModule.Runtime);
            _mappingHandler = new MappingHandler();
            bool hadStrongName = PrimaryAssemblyDefinition.Name.HasPublicKey;

            ModuleKind kind = PrimaryAssemblyMainModule.Kind;

            if (Options.TargetKind.HasValue)
            {
                switch (Options.TargetKind.Value)
                {
                case Kind.Dll: kind = ModuleKind.Dll; break;

                case Kind.Exe: kind = ModuleKind.Console; break;

                case Kind.WinExe: kind = ModuleKind.Windows; break;
                }
            }
            TargetRuntime runtime = ParseTargetPlatform();

            // change assembly's name to correspond to the file we create
            string mainModuleName = Path.GetFileNameWithoutExtension(Options.OutputFile);

            if (TargetAssemblyDefinition == null)
            {
                AssemblyNameDefinition asmName = Clone(PrimaryAssemblyDefinition.Name);
                asmName.Name             = mainModuleName;
                TargetAssemblyDefinition = AssemblyDefinition.CreateAssembly(asmName, mainModuleName,
                                                                             new ModuleParameters()
                {
                    Kind             = kind,
                    Architecture     = PrimaryAssemblyMainModule.Architecture,
                    AssemblyResolver = GlobalAssemblyResolver,
                    Runtime          = runtime
                });
            }
            else
            {
                // TODO: does this work or is there more to do?
                TargetAssemblyMainModule.Kind    = kind;
                TargetAssemblyMainModule.Runtime = runtime;

                TargetAssemblyDefinition.Name.Name = mainModuleName;
                TargetAssemblyMainModule.Name      = mainModuleName;
            }
            // set the main module attributes
            TargetAssemblyMainModule.Attributes             = PrimaryAssemblyMainModule.Attributes;
            TargetAssemblyMainModule.Win32ResourceDirectory = MergeWin32Resources(PrimaryAssemblyMainModule.Win32ResourceDirectory);

            if (Options.Version != null)
            {
                TargetAssemblyDefinition.Name.Version = Options.Version;
            }

            _lineIndexer = new IKVMLineIndexer(this);
            var signingStep = new SigningStep(this, Options);

            List <IRepackStep> repackSteps = new List <IRepackStep>
            {
                signingStep,
                new ReferencesRepackStep(Logger, this),
                new TypesRepackStep(Logger, this, _repackImporter, Options),
                new ResourcesRepackStep(Logger, this, Options),
                new AttributesRepackStep(Logger, this, _repackImporter, Options),
                new ReferencesFixStep(Logger, this, _repackImporter, Options),
                new XamlResourcePathPatcherStep(Logger, this)
            };

            foreach (var step in repackSteps)
            {
                step.Perform();
            }

            var parameters = new WriterParameters
            {
                StrongNameKeyPair = signingStep.KeyPair,
                WriteSymbols      = Options.DebugInfo
            };
            // create output directory if it does not exist
            var outputDir = Path.GetDirectoryName(Options.OutputFile);

            if (!string.IsNullOrEmpty(outputDir) && !Directory.Exists(outputDir))
            {
                Logger.Info("Output directory does not exist. Creating output directory: " + outputDir);
                Directory.CreateDirectory(outputDir);
            }
            TargetAssemblyDefinition.Write(Options.OutputFile, parameters);
            Logger.Info("Writing output assembly to disk");
            // If this is an executable and we are on linux/osx we should copy file permissions from
            // the primary assembly
            if (Environment.OSVersion.Platform == PlatformID.MacOSX || Environment.OSVersion.Platform == PlatformID.Unix)
            {
                Stat stat;
                Logger.Info("Copying permissions from " + PrimaryAssemblyFile);
                Syscall.stat(PrimaryAssemblyFile, out stat);
                Syscall.chmod(Options.OutputFile, stat.st_mode);
            }
            if (hadStrongName && !TargetAssemblyDefinition.Name.HasPublicKey)
            {
                Options.StrongNameLost = true;
            }

            // nice to have, merge .config (assembly configuration file) & .xml (assembly documentation)
            ConfigMerger.Process(this);
            if (Options.XmlDocumentation)
            {
                DocumentationMerger.Process(this);
            }

            // TODO: we're done here, the code below is only test code which can be removed once it's all running fine
            // 'verify' generated assembly
            AssemblyDefinition asm2 = AssemblyDefinition.ReadAssembly(Options.OutputFile, new ReaderParameters(ReadingMode.Immediate)
            {
                AssemblyResolver = GlobalAssemblyResolver
            });
            // lazy match on the name (not full) to catch requirements about merging different versions
            bool failed = false;

            foreach (var a in asm2.MainModule.AssemblyReferences.Where(x => MergedAssemblies.Any(y => Options.KeepOtherVersionReferences ? x.FullName == y.FullName : x.Name == y.Name.Name)))
            {
                // failed
                Logger.Error("Merged assembly still references " + a.FullName);
                failed = true;
            }
            if (failed)
            {
                throw new Exception("Merging failed, see above errors");
            }
        }
Beispiel #5
0
        /// <summary>
        /// The actual repacking process, called by main after parsing arguments.
        /// When referencing this assembly, call this after setting the merge properties.
        /// </summary>
        public void Repack()
        {
            var timer = new Stopwatch();

            timer.Start();
            Options.Validate();
            PrintRepackVersion();
            _reflectionHelper = new ReflectionHelper(this);
            ResolveSearchDirectories();

            // Read input assemblies only after all properties are set.
            ReadInputAssemblies();
            GlobalAssemblyResolver.RegisterAssemblies(MergedAssemblies);

            _platformFixer  = new PlatformFixer(this, PrimaryAssemblyMainModule.Runtime);
            _mappingHandler = new MappingHandler();
            bool hadStrongName = PrimaryAssemblyDefinition.Name.HasPublicKey;

            ModuleKind kind = PrimaryAssemblyMainModule.Kind;

            if (Options.TargetKind.HasValue)
            {
                switch (Options.TargetKind.Value)
                {
                case Kind.Dll: kind = ModuleKind.Dll; break;

                case Kind.Exe: kind = ModuleKind.Console; break;

                case Kind.WinExe: kind = ModuleKind.Windows; break;
                }
            }
            TargetRuntime runtime = ParseTargetPlatform();

            // change assembly's name to correspond to the file we create
            string mainModuleName = Path.GetFileNameWithoutExtension(Options.OutputFile);

            if (TargetAssemblyDefinition == null)
            {
                AssemblyNameDefinition asmName = Clone(PrimaryAssemblyDefinition.Name);
                asmName.Name             = mainModuleName;
                TargetAssemblyDefinition = AssemblyDefinition.CreateAssembly(asmName, mainModuleName,
                                                                             new ModuleParameters()
                {
                    Kind             = kind,
                    Architecture     = PrimaryAssemblyMainModule.Architecture,
                    AssemblyResolver = GlobalAssemblyResolver,
                    Runtime          = runtime
                });
            }
            else
            {
                // TODO: does this work or is there more to do?
                TargetAssemblyMainModule.Kind    = kind;
                TargetAssemblyMainModule.Runtime = runtime;

                TargetAssemblyDefinition.Name.Name = mainModuleName;
                TargetAssemblyMainModule.Name      = mainModuleName;
            }
            // set the main module attributes
            TargetAssemblyMainModule.Attributes             = PrimaryAssemblyMainModule.Attributes;
            TargetAssemblyMainModule.Win32ResourceDirectory = MergeWin32Resources(PrimaryAssemblyMainModule.Win32ResourceDirectory);

            if (Options.Version != null)
            {
                TargetAssemblyDefinition.Name.Version = Options.Version;
            }

            _lineIndexer = new IKVMLineIndexer(this, Options.LineIndexation);
            var signingStep = new SigningStep(this, Options);
            var sourceServerDataRepackStep = new SourceServerDataRepackStep(Options.OutputFile, MergedAssemblyFiles);

            List <IRepackStep> repackSteps = new List <IRepackStep>
            {
                signingStep,
                new ReferencesRepackStep(Logger, this),
                new TypesRepackStep(Logger, this, _repackImporter, Options),
                new ResourcesRepackStep(Logger, this, Options),
                new AttributesRepackStep(Logger, this, _repackImporter, Options),
                new ReferencesFixStep(Logger, this, _repackImporter, Options),
                new XamlResourcePathPatcherStep(Logger, this),
                sourceServerDataRepackStep
            };

            foreach (var step in repackSteps)
            {
                step.Perform();
            }

            var parameters = new WriterParameters
            {
                StrongNameKeyPair = signingStep.KeyPair,
                WriteSymbols      = Options.DebugInfo
            };
            // create output directory if it does not exist
            var outputDir = Path.GetDirectoryName(Options.OutputFile);

            if (!string.IsNullOrEmpty(outputDir) && !Directory.Exists(outputDir))
            {
                Logger.Info("Output directory does not exist. Creating output directory: " + outputDir);
                Directory.CreateDirectory(outputDir);
            }
            TargetAssemblyDefinition.Write(Options.OutputFile, parameters);
            sourceServerDataRepackStep.Write();
            Logger.Info("Writing output assembly to disk");
            // If this is an executable and we are on linux/osx we should copy file permissions from
            // the primary assembly
            if (Environment.OSVersion.Platform == PlatformID.MacOSX || Environment.OSVersion.Platform == PlatformID.Unix)
            {
                Stat stat;
                Logger.Info("Copying permissions from " + PrimaryAssemblyFile);
                Syscall.stat(PrimaryAssemblyFile, out stat);
                Syscall.chmod(Options.OutputFile, stat.st_mode);
            }
            if (hadStrongName && !TargetAssemblyDefinition.Name.HasPublicKey)
            {
                Options.StrongNameLost = true;
            }

            // nice to have, merge .config (assembly configuration file) & .xml (assembly documentation)
            ConfigMerger.Process(this);
            if (Options.XmlDocumentation)
            {
                DocumentationMerger.Process(this);
            }
            Logger.Info($"Finished in {timer.Elapsed}");
        }