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); }
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); }
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); }
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; }
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); }
/// <summary> /// Executes ILRepack with specified options. /// </summary> /// <returns>Returns true if its successful.</returns> public override bool Execute() { _repackOptions = new RepackOptions { KeyFile = _keyFile, KeyContainer = _keyContainer, LogFile = _logFile, Log = !string.IsNullOrEmpty(_logFile), LogVerbose = Verbose, UnionMerge = Union, DebugInfo = DebugInfo, CopyAttributes = CopyAttributes, AttributeFile = AttributeFile, AllowMultipleAssemblyLevelAttributes = AllowMultiple, TargetKind = _targetKind, TargetPlatformVersion = TargetPlatformVersion, TargetPlatformDirectory = TargetPlatformDirectory, XmlDocumentation = XmlDocumentation, Internalize = Internalize, DelaySign = DelaySign, AllowDuplicateResources = AllowDuplicateResources, AllowZeroPeKind = ZeroPeKind, Parallel = Parallel, PauseBeforeExit = PauseBeforeExit, OutputFile = _outputFile, AllowWildCards = Wildcards }; _ilMerger = new ILRepacking.ILRepack(_repackOptions); // Attempt to create output directory if it does not exist. var outputPath = Path.GetDirectoryName(OutputFile); if (outputPath != null && !Directory.Exists(outputPath)) { try { Directory.CreateDirectory(outputPath); } catch (Exception ex) { Log.LogErrorFromException(ex); return(false); } } // Assemblies to be merged. var assemblies = new string[_assemblies.Length]; for (int i = 0; i < _assemblies.Length; i++) { assemblies[i] = _assemblies[i].ItemSpec; if (string.IsNullOrEmpty(assemblies[i])) { throw new Exception($"Invalid assembly path on item index {i}"); } if (!File.Exists(assemblies[i]) && !File.Exists(BuildPath(assemblies[i]))) { throw new Exception($"Unable to resolve assembly '{assemblies[i]}'"); } Log.LogMessage(MessageImportance.High, "Added assembly '{0}'", assemblies[i]); } // List of regex to compare against FullName of types NOT to internalize if (InternalizeExclude != null) { var internalizeExclude = new string[InternalizeExclude.Length]; if (Internalize) { for (int i = 0; i < InternalizeExclude.Length; i++) { internalizeExclude[i] = InternalizeExclude[i].ItemSpec; if (string.IsNullOrEmpty(internalizeExclude[i])) { throw new Exception($"Invalid internalize exclude pattern at item index {i}. Pattern cannot be blank."); } Log.LogMessage(MessageImportance.High, "Excluding namespaces/types matching pattern '{0}' from being internalized", internalizeExclude[i]); } // Create a temporary file with a list of assemblies that should not be internalized. _excludeFileTmpPath = Path.GetTempFileName(); File.WriteAllLines(_excludeFileTmpPath, internalizeExclude); _repackOptions.ExcludeFile = _excludeFileTmpPath; } } _repackOptions.InputAssemblies = assemblies; // Path that will be used when searching for assemblies to merge. var searchPath = new List <string> { "." }; searchPath.AddRange(LibraryPath.Select(iti => BuildPath(iti.ItemSpec))); _repackOptions.SearchDirectories = searchPath.ToArray(); // Attempt to merge assemblies. try { Log.LogMessage(MessageImportance.High, "Merging {0} assemb{1} to '{2}'", _assemblies.Length, _assemblies.Length != 1 ? "ies" : "y", _outputFile); // Measure performance Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); _ilMerger.Repack(); stopWatch.Stop(); Log.LogMessage(MessageImportance.High, "Merge succeeded in {0} s", stopWatch.Elapsed.TotalSeconds); } catch (Exception e) { Log.LogErrorFromException(e); return(false); } return(true); }
public override bool Execute() { var basePath = Path.GetDirectoryName(BuildEngine.ProjectFileOfTaskNode); IEnumerable <string> ExpandPath(IEnumerable <string> paths) => paths.Select(p => Path.GetFullPath(Path.Combine(basePath, p))); var searchPaths = new List <string> (ExpandPath(SearchDirectories)); var inputAssemblies = new List <string> (ExpandPath(InputAssemblies)); var outputAssembly = OutputAssembly ?? InputAssemblies [0]; foreach (var reference in ExpandPath(References)) { var searchPath = Path.GetDirectoryName(reference); if (!IsNetstandardLibrary(reference) && !inputAssemblies.Contains(reference, StringComparer.OrdinalIgnoreCase)) { inputAssemblies.Add(reference); } else if (!searchPaths.Contains(searchPath, StringComparer.OrdinalIgnoreCase)) { searchPaths.Add(searchPath); } } Log.LogMessage(MessageImportance.Normal, "Output Assembly: {0}", outputAssembly); Log.LogMessage(MessageImportance.Normal, "Internalize: {0}", outputAssembly); foreach (var searchPath in searchPaths) { Log.LogMessage(MessageImportance.Normal, "Search Path: {0}", searchPath); } foreach (var inputAssembly in inputAssemblies) { Log.LogMessage(MessageImportance.Normal, "Input Assembly: {0}", inputAssembly); } var resolver = new DefaultAssemblyResolver(); foreach (var searchPath in searchPaths) { resolver.AddSearchDirectory(searchPath); } var readerParameters = new ReaderParameters { AssemblyResolver = resolver, ReadingMode = ReadingMode.Immediate }; var renames = new List <(Regex regex, string replacement)> (); foreach (var rename in NamespaceRenames) { renames.Add((new Regex(rename.ItemSpec), rename.GetMetadata("Replacement"))); } var typesToRenamespace = new HashSet <string> (); var renamespaceMap = new Dictionary <string, string> (); for (int i = 1; i < inputAssemblies.Count; i++) { using (var assemblyDefinition = AssemblyDefinition.ReadAssembly(inputAssemblies [i], readerParameters)) { foreach (var typeDefinition in assemblyDefinition.MainModule.Types) { typesToRenamespace.Add(typeDefinition.FullName); if (renamespaceMap.ContainsKey(typeDefinition.Namespace)) { continue; } var newNamespace = typeDefinition.Namespace; foreach (var rename in renames) { newNamespace = rename.regex.Replace(newNamespace, rename.replacement); } if (newNamespace == typeDefinition.Namespace) { renamespaceMap.Add(typeDefinition.Namespace, $"<{Guid.NewGuid ()}>{newNamespace}"); } else { renamespaceMap.Add(typeDefinition.Namespace, newNamespace); } } } } var options = new RepackOptions { InputAssemblies = inputAssemblies.ToArray(), SearchDirectories = searchPaths, Internalize = true, OutputFile = outputAssembly }; var repack = new ILRepacking.ILRepack(options, this); try { repack.Repack(); } catch (DllNotFoundException) { } var renamedAssembly = outputAssembly + ".renamed"; using (var assemblyDefinition = AssemblyDefinition.ReadAssembly(outputAssembly, readerParameters)) { foreach (var typeDefinition in CollectTypeDefinitions(assemblyDefinition)) { if (!typeDefinition.IsPublic && typesToRenamespace.Contains(typeDefinition.FullName)) { typeDefinition.Namespace = renamespaceMap [typeDefinition.Namespace]; } } assemblyDefinition.Write(renamedAssembly); } File.Delete(outputAssembly); File.Move(renamedAssembly, outputAssembly); return(true); }
public static void PatchBuildTasksInPackage(string packagePath) { using (var archive = new ZipArchive(File.Open(packagePath, FileMode.Open, FileAccess.ReadWrite), ZipArchiveMode.Update)) { foreach (var entry in archive.Entries.ToList()) { if (entry.Name == "Avalonia.Build.Tasks.dll") { var temp = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".dll"); var output = temp + ".output"; var patched = new MemoryStream(); try { entry.ExtractToFile(temp, true); var repack = new ILRepacking.ILRepack(new RepackOptions() { Internalize = true, InputAssemblies = new[] { temp, typeof(Mono.Cecil.AssemblyDefinition).Assembly.GetModules()[0] .FullyQualifiedName }, SearchDirectories = new string[0], OutputFile = output }); repack.Repack(); // 'hurr-durr assembly with the same name is already loaded' prevention using (var asm = AssemblyDefinition.ReadAssembly(output, new ReaderParameters { ReadWrite = true, InMemory = true, })) { asm.Name = new AssemblyNameDefinition( "Avalonia.Build.Tasks." + Guid.NewGuid().ToString().Replace("-", ""), new Version(0, 0, 0)); asm.Write(patched); patched.Position = 0; } } finally { try { if (File.Exists(temp)) { File.Delete(temp); } if (File.Exists(output)) { File.Delete(output); } } catch { //ignore } } var fn = entry.FullName; entry.Delete(); var newEntry = archive.CreateEntry(fn, CompressionLevel.Optimal); using (var s = newEntry.Open()) patched.CopyTo(s); } } } }
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); }
public static void DoRepackForCmd(IEnumerable <string> args) { var repack = new ILRepacking.ILRepack(new RepackOptions(args.Concat(new[] { "/log" }))); repack.Repack(); }
public override bool Execute() { var(inputAssemblies, searchPrefixes) = FilterInputAssemblies(InputAssemblies); var searchDirectories = new List <string> (); searchDirectories.AddRange(ResolvePaths(SearchDirectories) .Select(path => { if (File.Exists(path)) { return(Path.GetDirectoryName(path)); } return(path); })); searchDirectories.AddRange(searchPrefixes); Log.LogMessage(MessageImportance.Normal, "Input Assemblies:"); foreach (var inputAssembly in inputAssemblies) { Log.LogMessage(MessageImportance.Normal, $" {inputAssembly}"); } Log.LogMessage(MessageImportance.Normal, "Search Directories:"); foreach (var searchDirectory in searchDirectories) { Log.LogMessage(MessageImportance.Normal, $" {searchDirectory}"); } var repackOptions = new RepackOptions { OutputFile = PathHelpers.ResolveFullPath(OutputFile), InputAssemblies = inputAssemblies, SearchDirectories = searchDirectories.ToArray(), Internalize = Internalize, AllowDuplicateResources = AllowDuplicateResources, AllowMultipleAssemblyLevelAttributes = AllowMultipleAssemblyLevelAttributes, AllowWildCards = AllowWildCards, AllowZeroPeKind = AllowZeroPeKind, AttributeFile = AttributeFile, CopyAttributes = CopyAttributes, DebugInfo = DebugInfo, DelaySign = DelaySign, KeyFile = KeyFile, KeyContainer = KeyContainer, Parallel = Parallel, StrongNameLost = StrongNameLost, TargetKind = TargetKind == null ? null : (RepackKind?)Enum.Parse(typeof(RepackKind), TargetKind), TargetPlatformDirectory = TargetPlatformDirectory, TargetPlatformVersion = TargetPlatformVersion, UnionMerge = UnionMerge, Version = Version == null ? null : System.Version.Parse(Version), XmlDocumentation = XmlDocumentation, NoRepackRes = NoRepackRes, KeepOtherVersionReferences = KeepOtherVersionReferences, LineIndexation = LineIndexation, ExcludeFile = ExcludeFile }; if (ExcludeInternalizeMatches != null) { foreach (var matchRegex in ExcludeInternalizeMatches) { repackOptions.ExcludeInternalizeMatches.Add(new Regex(matchRegex)); } } if (AllowedDuplicateTypes != null) { foreach (var typeName in AllowedDuplicateTypes) { if (typeName.EndsWith(".*", StringComparison.InvariantCulture)) { repackOptions.AllowedDuplicateNameSpaces.Add( typeName.Substring(0, typeName.Length - 2)); } else { repackOptions.AllowedDuplicateTypes [typeName] = typeName; } } } if (AllowedDuplicateNameSpaces != null) { repackOptions.AllowedDuplicateNameSpaces.AddRange(AllowedDuplicateNameSpaces); } repackOptions.Log = true; repackOptions.LogVerbose = true; var repack = new ILRepacking.ILRepack( repackOptions, new ILRepackMSBuildLogger(Log)); repack.Repack(); return(true); }