private static void Merge(string dll) { var assemblyDefinition = AssemblyDefinition.ReadAssembly(dll); var moduleDefinition = assemblyDefinition.MainModule; var backup = $"{dll}.backup"; if (Util.Util.GetDefinition(moduleDefinition.Types, "TSML.Core", true) == null) { File.Copy(dll, backup, true); } assemblyDefinition.Dispose(); var options = new RepackOptions { OutputFile = dll, InputAssemblies = new[] { backup, "./TSML.dll" }, SearchDirectories = new List <string>().AsEnumerable(), TargetKind = ILRepack.Kind.Dll }; new ILRepack(options).Repack(); }
protected void InjectFarmhandCoreClasses(string output, params string[] inputs) { RepackOptions options = new RepackOptions(); ILogger logger = new RepackLogger(); try { options.InputAssemblies = inputs; options.OutputFile = output; options.DebugInfo = true; options.SearchDirectories = new[] { Directory.GetCurrentDirectory() }; var repack = new ILRepack(options, logger); repack.Repack(); } catch (Exception ex) { Console.WriteLine($"FATAL ERROR: ILRepack: {ex.Message}"); throw new Exception("ILRepack Error", ex); // ignored } finally { if (options.PauseBeforeExit) { Console.WriteLine("Press Any Key To Continue"); Console.ReadKey(true); } } }
public TypesRepackStep( ILogger logger, IRepackContext repackContext, IRepackImporter repackImporter, RepackOptions repackOptions) { _logger = logger; _repackContext = repackContext; _repackImporter = repackImporter as RepackImporter; _repackOptions = repackOptions; var types = _repackContext.OtherAssemblies.Concat(new[] { _repackContext.PrimaryAssemblyDefinition }) .SelectMany(x => x.Modules) .SelectMany(m => m.Types) .ToList(); if (_repackOptions.OptMode == OptionMode.merge) { _allTypes = types; } else { _allTypes = StripTypes(types); } }
private void Merge(string asmLoc, string asmBacLoc, string sfmfLoc) { AssemblyDefinition asmDef = AssemblyDefinition.ReadAssembly(asmLoc); ModuleDefinition modDef = asmDef.MainModule; if (Util.Util.GetDefinition(modDef.Types, "SFMF.Core", true) == null) { File.Copy(asmLoc, asmBacLoc, true); } var options = new RepackOptions { OutputFile = asmLoc, InputAssemblies = new[] { asmBacLoc, sfmfLoc }, SearchDirectories = new List <string>().AsEnumerable(), TargetKind = ILRepack.Kind.Dll }; var repack = new ILRepack(options); repack.Repack(); Dispatcher.Invoke(new Action(delegate() { PgbLoad.Value = 75; RefreshButtonStates(); })); }
public static void Merge(string asmLoc, string asmBacLoc, string sfmfLoc) { AssemblyDefinition asmDef = AssemblyDefinition.ReadAssembly(asmLoc); ModuleDefinition modDef = asmDef.MainModule; if (Util.Util.GetDefinition(modDef.Types, "SFMF.Core", true) == null) { File.Copy(asmLoc, asmBacLoc, true); } var options = new RepackOptions { OutputFile = asmLoc, InputAssemblies = new[] { asmBacLoc, sfmfLoc }, SearchDirectories = new List <string>().AsEnumerable(), TargetKind = ILRepack.Kind.Dll }; var repack = new ILRepack(options); repack.Repack(); }
public void SetUp() { repackLogger = new Mock <ILogger>(); commandLine = new Mock <ICommandLine>(); file = new Mock <IFile>(); options = new RepackOptions(commandLine.Object, repackLogger.Object, file.Object); }
public SigningStep( IRepackContext repackContext, RepackOptions repackOptions) { _repackContext = repackContext; _repackOptions = 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); }
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}"); } }
public ResourcesRepackStep( ILogger logger, IRepackContext repackContext, RepackOptions options) { _logger = logger; _options = options; _repackContext = repackContext; _targetAssemblyMainModule = _repackContext.TargetAssemblyMainModule; }
public ReferencesFixStep( ILogger logger, IRepackContext repackContext, IRepackImporter repackImporter, RepackOptions options) { _logger = logger; _repackContext = repackContext; _repackImporter = repackImporter; _options = options; }
public AttributesRepackStep( ILogger logger, IRepackContext repackContext, IRepackCopier repackCopier, RepackOptions options) { _logger = logger; _repackContext = repackContext; _repackCopier = repackCopier; _options = options; }
public TypesRepackStep( ILogger logger, IRepackContext repackContext, IRepackImporter repackImporter, RepackOptions repackOptions) { _logger = logger; _repackContext = repackContext; _repackImporter = repackImporter; _repackOptions = repackOptions; }
public void CreateMergedPackage(string packageFile) { if (packageFile == null) { throw new ArgumentNullException(nameof(packageFile)); } foreach (var consolidation in consolidations.Values) { var consolidatedAssemblyFile = Path.Combine( Path.GetDirectoryName(consolidation.Assemblies [0]), packageBuilder.Id + ".dll"); var repackOptions = new RepackOptions { OutputFile = consolidatedAssemblyFile, SearchDirectories = consolidation.AssemblySearchPaths.Concat(assemblySearchPaths), InputAssemblies = consolidation.Assemblies.ToArray(), Log = true, LogVerbose = true }; var repack = repackLogger == null ? new ILRepacking.ILRepack(repackOptions) : new ILRepacking.ILRepack(repackOptions, repackLogger); repack.Repack(); packageBuilder.FrameworkReferences.AddRange( consolidation.FrameworkAssemblyReferences.OrderBy(o => o.AssemblyName)); packageBuilder.Files.Add(new PhysicalPackageFile { SourcePath = consolidatedAssemblyFile, TargetPath = consolidatedAssemblyFile.Substring(workPath.Length) }); } var filteredDependencyGroups = packageBuilder .DependencyGroups .Select(dg => new PackageDependencyGroup( dg.TargetFramework, dg.Packages.Where(p => !consolidatedPackageIds.Contains(p.Id)))) .ToList(); packageBuilder.DependencyGroups.Clear(); packageBuilder.DependencyGroups.AddRange(filteredDependencyGroups); Directory.CreateDirectory(Path.GetDirectoryName(packageFile)); using (var mergedStream = File.Open( packageFile, FileMode.OpenOrCreate, FileAccess.ReadWrite)) packageBuilder.Save(mergedStream); }
public TypesRepackStep( ILogger logger, IRepackContext repackContext, IRepackImporter repackImporter, RepackOptions repackOptions) { _logger = logger; _repackContext = repackContext; _repackImporter = repackImporter; _repackOptions = repackOptions; _allTypes = _repackContext.OtherAssemblies.Concat(new[] { _repackContext.PrimaryAssemblyDefinition }) .SelectMany(x => x.Modules) .SelectMany(m => m.Types) .ToList(); }
static void Repack(string input, string[] extras, string output, string name = null) { Console.Error.WriteLine($"Repacking: {input} -> {output}"); if (name == null) { name = Path.GetFileName(output); } string outputTmp = Path.Combine(Path.GetDirectoryName(output), name); if (File.Exists(outputTmp)) { File.Delete(outputTmp); } List <string> args = new List <string>(); args.Add($"/out:{outputTmp}"); args.Add(input); foreach (string dep in extras) { if (!string.IsNullOrWhiteSpace(dep)) { args.Add(dep.Trim()); } } RepackOptions options = new RepackOptions(args); ILRepack repack = new ILRepack(options); repack.Repack(); if (output != outputTmp) { if (File.Exists(output)) { File.Delete(output); } File.Move(outputTmp, output); } }
/// <summary> /// Injects Farmhand assemblies into the game's executable /// </summary> /// <param name="output"> /// The output path /// </param> /// <param name="inputs"> /// The assemblies to merge /// </param> /// <exception cref="Exception"> /// Throws an exception if ILRepack fails. /// </exception> protected void InjectFarmhandCoreClasses(string output, params string[] inputs) { var options = new RepackOptions(); ILogger logger = new RepackLogger(); try { options.InputAssemblies = string.IsNullOrEmpty(this.Options.AssemblyDirectory) ? inputs : inputs.Select( n => Path.IsPathRooted(n) ? n : Path.Combine(this.Options.AssemblyDirectory, n)).ToArray(); options.OutputFile = output; options.DebugInfo = true; options.SearchDirectories = string.IsNullOrEmpty(this.Options.AssemblyDirectory) ? new[] { Directory.GetCurrentDirectory() } : new[] { this.Options.AssemblyDirectory }; var repack = new ILRepack(options, logger); repack.Repack(); } catch (Exception ex) { Console.WriteLine($"FATAL ERROR: ILRepack: {ex.Message}"); throw new Exception("ILRepack Error", ex); } finally { if (options.PauseBeforeExit) { Console.WriteLine("Press Any Key To Continue"); Console.ReadKey(true); } } }
public static void IlRepackCli(Context context) { var frameworks = context.GetSubDirectories(context.CliPackageDir) .Where(x => context.FileExists(x.CombineWithFilePath("VGAudioCli.exe"))); foreach (DirectoryPath tfm in frameworks) { DirectoryPath outDir = context.CliPackageDir.Combine($"{tfm.GetDirectoryName()}_standalone"); context.EnsureDirectoryExists(outDir); var libraries = context.GetFiles($"{tfm}/VGAudio.*dll"); var cliList = new List <FilePath> { tfm.CombineWithFilePath("VGAudioCli.exe") }; var toolsList = new List <FilePath> { tfm.CombineWithFilePath("VGAudioTools.exe") }; cliList.AddRange(libraries); toolsList.AddRange(libraries); var cliOptions = new RepackOptions { OutputFile = outDir.CombineWithFilePath("VGAudioCli.exe").FullPath, InputAssemblies = cliList.Select(x => x.FullPath).ToArray(), SearchDirectories = new[] { "." } }; var toolsOptions = new RepackOptions { OutputFile = outDir.CombineWithFilePath("VGAudioTools.exe").FullPath, InputAssemblies = toolsList.Select(x => x.FullPath).ToArray(), SearchDirectories = new[] { "." } }; new ILRepack(cliOptions).Repack(); new ILRepack(toolsOptions).Repack(); context.CopyFiles(context.GetFiles($"{outDir}/*.exe"), context.PackageDir); } }
/// <summary> /// Compiles a scene graph into a windows platform .NET executable. /// </summary> /// <param name="graph"> /// The specified scene graph to compile source from. /// </param> /// <returns> /// A Stream comprising the compilation output /// </returns> public static Stream Compile(SceneGraph graph, PlatformTarget platform = PlatformTarget.Windows) { Stream s; MemoryStream ms; ILRepack repack; RepackOptions options; string source; bool compiled; string tmpExeFile; string tmpExeFileRepacked; byte[] data; source = CompileAsObjects(graph); compiled = CompileCSharp(source, out tmpExeFile); tmpExeFileRepacked = Path.GetTempFileName() + ".exe"; options = new RepackOptions() { TargetKind = ILRepack.Kind.Exe, Parallel = true, Internalize = true, InputAssemblies = new string[] { tmpExeFile }, OutputFile = tmpExeFileRepacked }; repack = new ILRepack(options); data = File.ReadAllBytes(tmpExeFileRepacked); ms = new MemoryStream(data); s = ms; return(s); }
public void Merge(IEnumerable <string> assemblies, string outputPath) { var assembliesToMerge = assemblies?.ToList() ?? throw new ArgumentNullException(nameof(assemblies)); var assemblyResolver = new DefaultAssemblyResolver(); if (SearchDirectories != null) { foreach (var dir in SearchDirectories) { assemblyResolver.AddSearchDirectory(dir); } } if (Verbose) { Console.WriteLine("Merging:"); foreach (var include in assembliesToMerge) { Console.WriteLine($" - {include}"); } } var tempRoot = Path.Combine(Path.GetTempPath(), "Mono.ApiTools", "AssemblyMerger", Guid.NewGuid().ToString()); if (InjectAssemblyNames) { if (!string.IsNullOrWhiteSpace(tempRoot) && !Directory.Exists(tempRoot)) { Directory.CreateDirectory(tempRoot); } assembliesToMerge = assembliesToMerge.ToList(); for (int i = 0; i < assembliesToMerge.Count; i++) { var ass = assembliesToMerge[i]; var temp = Path.Combine(tempRoot, Guid.NewGuid().ToString() + ".dll"); InjectAssemblyName(assemblyResolver, ass, temp); assembliesToMerge[i] = temp; } if (Verbose) { Console.WriteLine("Temporary assemblies:"); foreach (var include in assembliesToMerge) { Console.WriteLine($" - {include}"); } } } var options = new RepackOptions { InputAssemblies = assembliesToMerge.ToArray(), OutputFile = outputPath, SearchDirectories = SearchDirectories.ToArray(), CopyAttributes = true, AllowMultipleAssemblyLevelAttributes = true, LogVerbose = Verbose }; options.AllowedDuplicateTypes.Add(InjectedAttributeFullName, InjectedAttributeFullName); var repacker = new ILRepack(options); repacker.Repack(); if (InjectAssemblyNames) { if (Directory.Exists(tempRoot)) { try { Directory.Delete(tempRoot, true); } catch { } } } }
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); }
/// <summary> /// Compiles this project to a DLL file. /// </summary> public void CompileToDLL(string generationPath) { //Set up compilation. string outputPath = Path.Combine(generationPath, ProjectName + ".dll"); string pdbPath = Path.Combine(generationPath, ProjectName + ".pdb"); //Generate syntax trees for all files. var trees = new List <SyntaxTree>(); foreach (var file in Files.Values) { try { trees.Add(CSharpSyntaxTree.ParseText(file)); } catch (Exception e) { Logger.Write("[ERR] - Internal compile error: '" + e.Message + "'.", 1); return; } } //Generate dependency references. var deps = new List <PortableExecutableReference>(); deps.Add(MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location)); //make sure to add system deps.Add(MetadataReference.CreateFromFile(typeof(Enumerable).GetTypeInfo().Assembly.Location)); //linq deps.Add(MetadataReference.CreateFromFile(typeof(BurritoCore.API).GetTypeInfo().Assembly.Location)); //api foreach (var dep in CompileDependencies) { deps.Add(MetadataReference.CreateFromFile(dep)); } //Compilation options. var compilationOpts = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary); //Set up compilation. CSharpCompilation compilation = CSharpCompilation.Create( ProjectName, trees.ToArray(), deps.ToArray(), compilationOpts); //Write to a DLL stream. using (var dllStream = new MemoryStream()) using (var pdbStream = new MemoryStream()) { var emitResult = compilation.Emit(dllStream, pdbStream); if (!emitResult.Success) { //Emit errors. foreach (var error in emitResult.Diagnostics) { Logger.Write("[ERR] - Internal compile error at '" + error.Location + "': " + error.GetMessage(), 1); } return; } //From the DLL stream, write to file. using (FileStream fs = new FileStream(outputPath, FileMode.OpenOrCreate)) { dllStream.WriteTo(fs); fs.Flush(); } //If debug information is enabled, flush PDB too. if (BurritoAPI.IncludeDebugInformation) { using (FileStream fs = new FileStream(pdbPath, FileMode.OpenOrCreate)) { pdbStream.WriteTo(fs); fs.Flush(); } } } //Set up options for merging DLL libraries (suppressing console input). RepackOptions opt = new RepackOptions(); opt.OutputFile = outputPath + ".packed"; opt.SearchDirectories = new string[] { Environment.CurrentDirectory, AppDomain.CurrentDomain.BaseDirectory }; //Setting input assemblies. opt.InputAssemblies = new string[] { outputPath }.Concat(CompileDependencies).ToArray(); //Redirecting console input temporarily. using (var writer = new ConsoleCatcher()) { //Set up writer. var originalOut = Console.Out; if (BurritoAPI.VerbosityLevel < 0) { Console.SetOut(writer); } //Merge. ILRepack pack = new ILRepack(opt); pack.Repack(); //Set input back. Console.SetOut(originalOut); } //Delete original assembly, rename packed. string packedName = outputPath + ".packed"; try { File.Delete(outputPath); File.Move(packedName, outputPath); } catch { Logger.Write("[WARN] - Failed renaming packed (.dll.packed) to normal (.dll), insufficient permissions. Job still completed.", 2); } }
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 ReferencesRepackStep(ILogger logger, IRepackContext repackContext, RepackOptions options) { _logger = logger; _repackContext = repackContext; _options = options; }
public void Merge(string outputPath) { var assemblies = Assemblies; if (Program.Verbose) { Console.WriteLine("Merging:"); foreach (var include in assemblies) { Console.WriteLine($" - {include}"); } } var tempRoot = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); if (InjectAssemblyNames) { assemblies = assemblies.ToList(); if (!Directory.Exists(tempRoot)) { Directory.CreateDirectory(tempRoot); } for (int i = 0; i < assemblies.Count; i++) { var ass = assemblies[i]; var temp = Path.Combine(tempRoot, Guid.NewGuid().ToString() + ".dll"); InjectAssemblyName(ass, temp); assemblies[i] = temp; } if (Program.Verbose) { Console.WriteLine("Temporary assemblies:"); foreach (var include in assemblies) { Console.WriteLine($" - {include}"); } } } var options = new RepackOptions { InputAssemblies = assemblies.ToArray(), OutputFile = outputPath, SearchDirectories = SearchDirectories.ToArray(), CopyAttributes = true, AllowMultipleAssemblyLevelAttributes = true, LogVerbose = Program.Verbose }; var repacker = new ILRepack(options); repacker.Repack(); if (InjectAssemblyNames) { MergeAssemblyNameAttributes(outputPath); if (Directory.Exists(tempRoot)) { Directory.Delete(tempRoot, true); } } }
//////////////////////////// /// MAIN COMPILE METHODS /// //////////////////////////// public static void Compile(string file) { //Print the compile header. PrintCompileHeader(); //Note the compile start time. CompileStartTime = DateTime.Now; //Does the file that is being compiled exist? if (!File.Exists(file)) { Error.FatalCompile("The file you wish to compile does not exist."); return; } //Get the FileInfo, set the name of the project. FileInfo fi = new FileInfo(file); if (fi.Name.Contains(".")) { ProjectName = fi.Name.Split('.')[0]; } else { ProjectName = fi.Name; } //Yes, read the file into memory and strip all the comments. Log("Linking base Algo file '" + file + "'."); string toCompile = ""; try { toCompile = File.ReadAllText(file); } catch (Exception e) { Error.FatalCompile("Could not read from base script file, error '" + e.Message + "'."); return; } //Attaching the "core" library to the start. Log("Attaching the 'core' library to the base script."); MainScript = "import \"core\";" + MainScript; //Strip all comment lines. var scriptLines = toCompile.Replace("\r", "").Split('\n'); foreach (var line in scriptLines) { if (!line.StartsWith("//")) { MainScript += line + "\n"; } } Log("Successfully linked main file, linking references..."); //Get all linked import reference files. LinkFile(MainScript, file); Log("Successfully linked base and all referenced Algo scripts.", ALECEvent.Success); //Replacing import references with their proper scripts. Log("Attempting to replace abstract import links..."); bool success = ReplaceImportReferences(); if (!success) { Error.FatalCompile("Failed to replace import links with script references. Do you have a circular import loop?"); return; } //Do a sanity check to make sure it compiles as normal Algo. Log("Sanity checking the syntax of the provided script..."); SyntaxCheck(MainScript, MainScript.Replace("\r", "").Split('\n').Length - scriptLines.Length); //That's done, now convert it to a literal string. Log("Converting script into literal form for compilation..."); MainScript = MainScript.Replace("\"", "\"\""); Log("Successfully converted into literal form."); //Create the compiler (with arguments). CSharpCodeProvider provider = new CSharpCodeProvider(); CompilerParameters cp = new CompilerParameters(); cp.GenerateExecutable = true; cp.OutputAssembly = ProjectName + ".exe"; cp.GenerateInMemory = false; //Reference the main Algo assembly (this one) when compiling. Assembly entryasm = Assembly.GetEntryAssembly(); if (AlgoPlatformInfo.IsWindows) { cp.ReferencedAssemblies.Add(entryasm.Location); } else { cp.ReferencedAssemblies.Add(CPFilePath.GetPlatformFilePath(new string[] { DefaultDirectories.AssemblyDirectory, "Algo.exe" })); } cp.ReferencedAssemblies.Add(CPFilePath.GetPlatformFilePath(new string[] { DefaultDirectories.AssemblyDirectory, "Antlr4.Runtime.dll" })); //Attempt to compile. string finalScript = ALECTemplates.ALECEntryPoint.Replace("[CUSTOM-CODE-HERE]", MainScript); CompilerResults results = provider.CompileAssemblyFromSource(cp, finalScript); if (results.Errors.HasErrors) { //Uh oh, failed. //Collect the errors. string final = "Attempting to compile returned some errors:\n"; List <string> errors = new List <string>(); foreach (CompilerError error in results.Errors) { errors.Add(error.ErrorText + " (Line " + error.Line + ", column " + error.Column + ")."); } for (int i = 0; i < errors.Count; i++) { final += "[" + (i + 1) + "] - " + errors[i] + "\n"; } //Log. Error.FatalCompile(final); return; } //Successfully compiled, try to output to file. Log("Successfully compiled the Algo script into assembly.", ALECEvent.Success); Log("Output has been saved in '" + ProjectName + ".exe'."); //If Linux, MKBundle. if (AlgoPlatformInfo.IsLinux) { //Attempt to run MKBundle. Log("Linux detected as the operating system, attempting to create a native binary..."); Log("MAKE SURE YOU HAVE MKBUNDLE INSTALLED, AND HAVE A MONO 'machine.config' AT /etc/mono/4.5/machine.config."); Process proc = new Process(); proc.StartInfo.FileName = "/bin/bash"; proc.StartInfo.Arguments = "-c \" mkbundle -o " + ProjectName + " --simple " + cp.OutputAssembly + " --machine-config /etc/mono/4.5/machine.config --no-config --nodeps " + CPFilePath.GetPlatformFilePath(new string[] { DefaultDirectories.AssemblyDirectory, "*.dll" }) + " " + CPFilePath.GetPlatformFilePath(new string[] { DefaultDirectories.AssemblyDirectory, "Algo.exe" }) + "\""; proc.StartInfo.UseShellExecute = false; proc.StartInfo.RedirectStandardOutput = true; proc.Start(); while (!proc.StandardOutput.EndOfStream) { Log(proc.StandardOutput.ReadLine()); } Log("MKBundle has finished executing."); //Delete the main executable. Log("Attempting to clean up..."); try { File.Delete(ProjectName + ".exe"); } catch (Exception e) { Error.WarningCompile("Failed to clean up Windows executable, given error '" + e.Message + "'."); } } else if (AlgoPlatformInfo.IsWindows) { //It's Windows, use ILRepack instead. Log("Windows detected as the operating system, attempting to create a native binary..."); Log("Attempting to bundle dependencies into packed executable..."); RepackOptions opt = new RepackOptions(); opt.OutputFile = ProjectName + "_packed.exe"; opt.SearchDirectories = new string[] { AppDomain.CurrentDomain.BaseDirectory, Environment.CurrentDirectory }; //Setting input assemblies. string[] files = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll"); opt.InputAssemblies = new string[] { ProjectName + ".exe", entryasm.Location }.Concat(files).ToArray(); try { //Merging. ILRepack pack = new ILRepack(opt); pack.Repack(); Log("Successfully merged all dependencies with the output executable.", ALECEvent.Success); //Replacing the depending executable with the new one. Log("Cleaning up build files..."); try { File.Delete(ProjectName + ".exe"); File.Move(ProjectName + "_packed.exe", ProjectName + ".exe"); } catch (Exception e) { Error.WarningCompile("File cleanup failed with error '" + e.Message + "'."); Error.WarningCompile("Failed to clean up build files, the executable to use is named '" + ProjectName + "_packed.exe' rather than '" + ProjectName + ".exe'."); } } catch (Exception e) { Error.WarningCompile("Packing the executable's dependencies failed, with error '" + e.Message + "'. You will need to include algo.exe and all it's dependencies along with the built executable for it to run."); } } else { Error.FatalCompile("Could not detect the operating system to compile native binary."); return; } //Print the compile footer. PrintCompileFooter(); return; }
public override Task Execute() { var(file, deps) = GetDeps(); var currentDir = Directory.GetCurrentDirectory(); string[] dlls = null; if (_options.MergeAll) { dlls = GetDllsFromDir(file, currentDir); } else { dlls = GetDllsFromDeps(deps); } if (dlls != null) { if (!string.IsNullOrWhiteSpace(_options.Exclude)) { //exclude special dlls dlls = dlls.Where(d => !IsMatch(_options.Exclude, d)).ToArray();//todo:will keep the order? } if (dlls.Length > 0) { foreach (var dll in dlls) { if (!File.Exists(Path.Combine(currentDir, dll))) { throw new Exception($"Can not find dll in current dir:{dll}"); } } MessageHelper.Info($"minify dlls:{string.Join(";", dlls)}"); var outDir = Path.Combine(currentDir, string.IsNullOrWhiteSpace(_options.Directory) ? "nustored" : _options.Directory); var outFile = Path.Combine(outDir, dlls.First()); var options = new RepackOptions() { DelaySign = _options.DelaySign, DebugInfo = _options.DebugInfo, SearchDirectories = _options.SearchDirectories ?? new string[0], LogVerbose = _options.Verbosity, OutputFile = outFile, InputAssemblies = dlls }; if (!string.IsNullOrWhiteSpace(_options.Kind)) { options.TargetKind = Enum.Parse <ILRepack.Kind>(_options.Kind, true); } var pack = new ILRepack(options, new PackLogger() { ShouldLogVerbose = _options.Verbosity }); pack.Repack(); //generate deps.json var hashDlls = new HashSet <string>(dlls.Skip(1).Select(d => Path.GetFileNameWithoutExtension(d)));// hold the main dll if (hashDlls.Any()) { if (deps.Targets != null) { foreach (var target in deps.Targets) { RemoveMergedDlls(target.Value, hashDlls); } } RemoveMergedDlls(deps.Libraries, hashDlls); } File.WriteAllText(Path.Combine(outDir, Path.GetFileName(file)), JsonConvert.SerializeObject(deps, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.Indented }), Encoding.UTF8); foreach (var filter in (_options.CopyFilters == null || _options.CopyFilters.Count() == 0 ? new[] { "appsettings.json" } : _options.CopyFilters)) { CopyFile(currentDir, filter, outDir); } //copy runtimeconfig CopyFile(currentDir, "*.runtimeconfig.*", outDir); MessageHelper.Successs($"minify completed. output:{outDir}"); } else { MessageHelper.Error("can not find/match dlls"); } } return(Task.CompletedTask); }
/// <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); }
void Parse() { options = new RepackOptions(commandLine.Object, file.Object); }