public static PackerAttribute Read(IAnnotationInstance annotation) { PackerAttribute config = new PackerAttribute(); MemberValuePairCollection namedArguments = annotation.Value.NamedArguments; config.DisableCleanup = namedArguments.GetSafeBool(nameof(PackerAttribute.DisableCleanup), false); config.DisableCompression = namedArguments.GetSafeBool(nameof(PackerAttribute.DisableCompression), false); config.IncludeDebugSymbols = namedArguments.GetSafeBool(nameof(PackerAttribute.IncludeDebugSymbols), true); config.LoadAtModuleInit = namedArguments.GetSafeBool(nameof(PackerAttribute.LoadAtModuleInit), true); config.CreateTemporaryAssemblies = namedArguments.GetSafeBool(nameof(PackerAttribute.CreateTemporaryAssemblies), false); config.IgnoreSatelliteAssemblies = namedArguments.GetSafeBool(nameof(PackerAttribute.IgnoreSatelliteAssemblies), false); config.IncludeAssemblies = namedArguments.GetSafeStringArray(nameof(PackerAttribute.IncludeAssemblies)); config.ExcludeAssemblies = namedArguments.GetSafeStringArray(nameof(PackerAttribute.ExcludeAssemblies)); config.PreloadOrder = namedArguments.GetSafeStringArray(nameof(PackerAttribute.PreloadOrder)); config.Unmanaged32Assemblies = namedArguments.GetSafeStringArray(nameof(PackerAttribute.Unmanaged32Assemblies)); config.Unmanaged64Assemblies = namedArguments.GetSafeStringArray(nameof(PackerAttribute.Unmanaged64Assemblies)); if (config.IncludeAssemblies != null && config.IncludeAssemblies.Length > 0 && config.ExcludeAssemblies != null && config.ExcludeAssemblies.Length > 0) { Message.Write(annotation.TargetElement, SeverityType.Error, "JOE01", "Set IncludeAssemblies, or ExcludeAssemblies, but not both."); } return(config); }
public void SynthesizeCallToAttach(PackerAttribute config, Project project, AssemblyLoaderInfo assemblyLoaderInfo) { var initialized = FindInitializeCalls(project, assemblyLoaderInfo); if (config.LoadAtModuleInit) { AddModuleInitializerCall(project, assemblyLoaderInfo); } else if (!initialized) { Message.Write(project.Module.Assembly.GetSystemAssembly(), SeverityType.Warning, "PACK01", "The add-in was not initialized. Make sure LoadAtModuleInit=true or call PackerUtility.Initialize()."); } }
public override bool Execute() { // Find configuration: var annotations = annotationsService.GetAnnotationsOfType(typeof(PackerAttribute), false, true); PackerAttribute config = new PackerAttribute(); if (annotations.MoveNext()) { config = Configuration.Read(annotations.Current); } // Find gatherable assemblies: string[] paths = Project.Properties["ReferenceCopyLocalPaths"]?.Split('|') ?? new string[0]; AssemblyManifestDeclaration manifest = Project.Module.AssemblyManifest; // I have no idea what this is doing: ResourceCaseFixer.FixResourceCase(manifest); // Embed resources: var checksums = new Checksums(); bool unmanagedFromProcessor = NativeResourcesProcessor.ProcessNativeResources(manifest, !config.DisableCompression, checksums); var resourceEmbedder = new ResourceEmbedder(manifest); resourceEmbedder.EmbedResources(config, paths, checksums); bool unmanagedFromEmbedder = resourceEmbedder.HasUnmanaged; // Load references: var assets = new Assets(Project.Module); AssemblyLoaderInfo info = AssemblyLoaderInfo.LoadAssemblyLoader(config.CreateTemporaryAssemblies, unmanagedFromEmbedder || unmanagedFromProcessor, Project.Module); // Alter code: string resourcesHash = ResourceHash.CalculateHash(manifest); new AttachCallSynthesis().SynthesizeCallToAttach(config, Project, info); new ResourceNameFinder(info, manifest, assets).FillInStaticConstructor( config.CreateTemporaryAssemblies, config.PreloadOrder, resourcesHash, checksums); return(true); }
public void EmbedResources(PackerAttribute config, string[] referenceCopyLocalPaths, Checksums checksums) { string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); cachePath = tempDirectory; // Path.Combine(Path.GetDirectoryName(AssemblyFilePath), "Costura"); Directory.CreateDirectory(cachePath); var onlyBinaries = referenceCopyLocalPaths.Where(x => x.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) || x.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)).ToArray(); var disableCompression = config.DisableCompression; var createTemporaryAssemblies = config.CreateTemporaryAssemblies; foreach (var dependency in GetFilteredReferences(onlyBinaries, config)) { var fullPath = Path.GetFullPath(dependency); if (!config.IgnoreSatelliteAssemblies) { if (dependency.EndsWith(".resources.dll", StringComparison.OrdinalIgnoreCase)) { Embed($"costura.{Path.GetFileName(Path.GetDirectoryName(fullPath))}.", fullPath, !disableCompression, createTemporaryAssemblies, config.DisableCleanup, checksums); continue; } } Embed("costura.", fullPath, !disableCompression, createTemporaryAssemblies, config.DisableCleanup, checksums); if (!config.IncludeDebugSymbols) { continue; } var pdbFullPath = Path.ChangeExtension(fullPath, "pdb"); if (File.Exists(pdbFullPath)) { Embed("costura.", pdbFullPath, !disableCompression, createTemporaryAssemblies, config.DisableCleanup, checksums); } } foreach (var dependency in onlyBinaries) { var prefix = ""; if (config.Unmanaged32Assemblies.Any(x => string.Equals(x, Path.GetFileNameWithoutExtension(dependency), StringComparison.OrdinalIgnoreCase))) { prefix = "costura32."; this.HasUnmanaged = true; } if (config.Unmanaged64Assemblies.Any(x => string.Equals(x, Path.GetFileNameWithoutExtension(dependency), StringComparison.OrdinalIgnoreCase))) { prefix = "costura64."; this.HasUnmanaged = true; } if (string.IsNullOrEmpty(prefix)) { continue; } var fullPath = Path.GetFullPath(dependency); Embed(prefix, fullPath, !disableCompression, true, config.DisableCleanup, checksums); if (!config.IncludeDebugSymbols) { continue; } var pdbFullPath = Path.ChangeExtension(fullPath, "pdb"); if (File.Exists(pdbFullPath)) { Embed(prefix, pdbFullPath, !disableCompression, true, config.DisableCleanup, checksums); } } }
IEnumerable <string> GetFilteredReferences(IEnumerable <string> onlyBinaries, PackerAttribute config) { if (config.IncludeAssemblies.Any()) { var skippedAssemblies = new List <string>(config.IncludeAssemblies); foreach (var file in onlyBinaries) { var assemblyName = Path.GetFileNameWithoutExtension(file); if (config.IncludeAssemblies.Any(x => CompareAssemblyName(x, assemblyName)) && config.Unmanaged32Assemblies.All(x => !CompareAssemblyName(x, assemblyName)) && config.Unmanaged64Assemblies.All(x => !CompareAssemblyName(x, assemblyName))) { skippedAssemblies.Remove(config.IncludeAssemblies.First(x => CompareAssemblyName(x, assemblyName))); yield return(file); } } if (skippedAssemblies.Count > 0) { var splittedReferences = new string[0];// References.Split(';'); var hasErrors = false; foreach (var skippedAssembly in skippedAssemblies) { var fileName = (from splittedReference in splittedReferences where string.Equals(Path.GetFileNameWithoutExtension(splittedReference), skippedAssembly, StringComparison.InvariantCulture) select splittedReference).FirstOrDefault(); if (string.IsNullOrEmpty(fileName)) { hasErrors = true; // TODO LogError($"Assembly '{skippedAssembly}' cannot be found (not even as CopyLocal='false'), please update the configuration"); continue; } yield return(fileName); } if (hasErrors) { throw new Exception("One or more errors occurred, please check the log"); } } yield break; } if (config.ExcludeAssemblies.Any()) { foreach (var file in onlyBinaries.Except(config.Unmanaged32Assemblies).Except(config.Unmanaged64Assemblies)) { var assemblyName = Path.GetFileNameWithoutExtension(file); if (config.ExcludeAssemblies.Any(x => CompareAssemblyName(x, assemblyName)) || config.Unmanaged32Assemblies.Any(x => CompareAssemblyName(x, assemblyName)) || config.Unmanaged64Assemblies.Any(x => CompareAssemblyName(x, assemblyName))) { continue; } yield return(file); } yield break; } if (config.OptOut) { foreach (var file in onlyBinaries) { var assemblyName = Path.GetFileNameWithoutExtension(file); if (config.Unmanaged32Assemblies.All(x => !CompareAssemblyName(x, assemblyName)) && config.Unmanaged64Assemblies.All(x => !CompareAssemblyName(x, assemblyName))) { yield return(file); } } } }