public override AssemblyElement CreateAssemblyElement(ModelElement model, string assemblyName, IncludeStatus includeStatus) { IncludeSet includeSet = (IncludeSet)model; TrimAssembly trimAssembly = new TrimAssembly(assemblyName, includeStatus);; includeSet.AddAssembly(trimAssembly); return(trimAssembly); }
public Trimmer(IncludeSet includeSet, bool changeVisibility, bool applyAnnotations, bool removeDesktopSecurity, HostEnvironment hostEnvironment, bool removeSerializabilityInfo, bool ensureConstructorsPresent, bool removeManifestResources) : base(hostEnvironment) { _includeSet = includeSet; _changeVisibility = changeVisibility; _applyAnnotations = applyAnnotations; _removeDesktopSecurity = removeDesktopSecurity; _removeSerializabilityInfo = removeSerializabilityInfo; _ensureConstructorsPresent = ensureConstructorsPresent; _removeManifestResources = removeManifestResources; _trimElements = new Stack<Element>(); _systemTypes = new List<string>{ "<Module>", }; // No need to include build-related types like AssemblyRef, FXAssembly, nor ThisAssembly }
public Trimmer(IncludeSet includeSet, bool changeVisibility, bool applyAnnotations, bool removeDesktopSecurity, HostEnvironment hostEnvironment, bool removeSerializabilityInfo, bool ensureConstructorsPresent, bool removeManifestResources) : base(hostEnvironment) { _includeSet = includeSet; _changeVisibility = changeVisibility; _applyAnnotations = applyAnnotations; _removeDesktopSecurity = removeDesktopSecurity; _removeSerializabilityInfo = removeSerializabilityInfo; _ensureConstructorsPresent = ensureConstructorsPresent; _removeManifestResources = removeManifestResources; _trimElements = new Stack <Element>(); _systemTypes = new List <string> { "<Module>", }; // No need to include build-related types like AssemblyRef, FXAssembly, nor ThisAssembly }
public Trimmer(IncludeSet includeSet, bool changeVisibility, bool applyAnnotations, bool removeDesktopSecurity, HostEnvironment hostEnvironment, bool removeSerializabilityInfo, bool ensureConstructorsPresent) : this(includeSet, changeVisibility, applyAnnotations, removeDesktopSecurity, hostEnvironment, removeSerializabilityInfo, false, false) { }
public static void RunBclRewriter(string[] args) { #region Parse the command-line arguments. if (!Parser.ParseArgumentsWithUsage(args, typeof(Program))) throw new UsageException(); #endregion #region Figure out paths s_assemblyName = Path.GetFullPath(s_assemblyName); // this has to be specified string outputBaseName = null; if (!String.IsNullOrEmpty(s_output)) { s_output = Path.GetFullPath(s_output); outputBaseName = Path.GetFileNameWithoutExtension(s_output); } else { s_output = Path.Combine(Directory.GetCurrentDirectory(), Path.GetFileNameWithoutExtension(s_assemblyName) + ".small" + Path.GetExtension(s_assemblyName)); outputBaseName = s_assemblyName; } string pdbSourceFile = Path.ChangeExtension(s_assemblyName, "pdb"); string outputPdb = Path.ChangeExtension(s_output, "pdb"); string outputFolder = Path.GetDirectoryName(s_output); // if the user wants to do an in-place rewrite, we copy the file to a temp file if (s_output == s_assemblyName) { String tempPath = s_assemblyName + TempExtension; String tempPdbPath = pdbSourceFile + TempExtension; File.Copy(s_assemblyName, tempPath, true); s_assemblyName = tempPath; if (File.Exists(pdbSourceFile)) { File.Copy(pdbSourceFile, tempPdbPath, true); pdbSourceFile = tempPdbPath; } } if (!Directory.Exists(outputFolder)) Directory.CreateDirectory(outputFolder); #endregion #region Load input files HostEnvironment host = new HostEnvironment(new NameTable(), s_assemblyDependencyPaths, s_referencedAssemblies); IAssembly/*?*/ assembly = host.LoadUnitFrom(s_assemblyName) as IAssembly; // TODO: Handle multimodule assemblies if (assembly == null || assembly == Dummy.Assembly) { throw new UsageException(args[0] + " is not a PE file containing a CLR assembly, or an error occurred when loading it."); } if (!File.Exists(s_includeListFile)) { throw new UsageException(String.Format("ERROR: Can't find code model file '{0}'", s_includeListFile)); } ThinModel model = new ThinModel(new ThinnerOptions(host, new AssemblyIdentity[] { assembly.AssemblyIdentity })); model.LoadModel(s_includeListFile, new ModelReaderOptions(s_platform, s_architecture, s_flavor, s_treatFxInternalAsPublic, s_defines)); #endregion #region Calculate api closure. ConsoleTimer.StartTimer("Calculating api closure"); model.LoadMetadataFrom(assembly); ThinModel apiClosure = model.CalculateApiClosure(); if (s_keepTempFiles) apiClosure.SaveModel(Path.ChangeExtension(s_output, ".apiClosure.xml")); ConsoleTimer.EndTimer("Calculating api closure"); #endregion #region Calculate impl closure. ConsoleTimer.StartTimer("Calculating implementation closure"); apiClosure.LoadMetadataFrom(assembly); ThinModel implClosure = apiClosure.CalculateImplementationClosure(true, FieldOptions.KeepAll); if (s_keepTempFiles) implClosure.SaveModel(Path.ChangeExtension(s_output, ".implClosure.xml")); ConsoleTimer.EndTimer("Calculating implementation closure"); #endregion #region Trim. ConsoleTimer.StartTimer("Trimming assembly"); IncludeSet includeSet = new IncludeSet(); includeSet.LoadFrom(implClosure); var copier = new MetadataDeepCopier(host); Assembly copiedAssembly = copier.Copy(assembly); Trimmer trimmer = new Trimmer(includeSet, true, false, true, host, s_removeSerializable); trimmer.RewriteChildren(copiedAssembly); Assembly mutableAssembly = copiedAssembly; assembly = mutableAssembly; ConsoleTimer.EndTimer("Trimming assembly"); #endregion #region Update assembly name. ConsoleTimer.StartTimer("Updating assembly name"); // If the output assembly name is different, update the internal assembly name to match. AssemblyIdentity originalAssemblyIdentity = mutableAssembly.AssemblyIdentity; if (!outputBaseName.Equals(originalAssemblyIdentity.Name.ToString(), StringComparison.OrdinalIgnoreCase)) { mutableAssembly.Name = host.NameTable.GetNameFor(outputBaseName); mutableAssembly.ModuleName = mutableAssembly.Name; } // If we changed the assembly identity, update references to it. if (!mutableAssembly.AssemblyIdentity.Equals(originalAssemblyIdentity)) { trimmer.UpdateAssemblyReferences(originalAssemblyIdentity, mutableAssembly.AssemblyIdentity); } ConsoleTimer.EndTimer("Updating assembly name"); #endregion #region Write out the assembly ConsoleTimer.StartTimer("Writing assembly"); PdbReader pdbReader = null; PdbWriter pdbWriter = null; if (File.Exists(pdbSourceFile)) { Stream pdbStream = File.OpenRead(pdbSourceFile); pdbReader = new PdbReader(pdbStream, host); pdbWriter = new PdbWriter(outputPdb, pdbReader); Console.WriteLine("Writing pdb: {0}", outputPdb); } Console.WriteLine("Writing assembly: {0}", s_output); FileStream file = File.Create(s_output); try { PeWriter.WritePeToStream(assembly, host, file, pdbReader, pdbReader, pdbWriter); } finally { if (file != null) { file.Dispose(); } if (pdbWriter != null) { pdbWriter.Dispose(); } } ConsoleTimer.EndTimer("Writing assembly"); #endregion }