예제 #1
0
파일: WeavingTask.cs 프로젝트: kswoll/Fody
        public override bool Execute()
        {
            var referenceCopyLocalPaths = ReferenceCopyLocalPaths.Select(x => x.ItemSpec).ToList();
            var defineConstants         = DefineConstants.GetConstants();

            processor = new Processor
            {
                Logger = new BuildLogger
                {
                    BuildEngine = BuildEngine,
                },
                AssemblyFilePath        = AssemblyPath,
                IntermediateDirectory   = IntermediateDir,
                KeyFilePath             = KeyFilePath,
                SignAssembly            = SignAssembly,
                ProjectDirectory        = ProjectDirectory,
                References              = References,
                SolutionDirectory       = SolutionDir,
                ReferenceCopyLocalPaths = referenceCopyLocalPaths,
                DefineConstants         = defineConstants,
                NuGetPackageRoot        = NuGetPackageRoot,
                PackageDefinitions      = PackageDefinitions?.ToList()
            };
            var success = processor.Execute();

            if (success)
            {
                var weavers = processor.Weavers.Select(x => x.AssemblyName);
                ExecutedWeavers = string.Join(";", weavers) + ";";
            }

            return(success);
        }
예제 #2
0
    string Embed(string prefix, string fullPath, bool compress)
    {
        var resourceName = $"{prefix}{Path.GetFileName(fullPath).ToLowerInvariant()}";

        if (ModuleDefinition.Resources.Any(x => string.Equals(x.Name, resourceName, StringComparison.OrdinalIgnoreCase)))
        {
            LogInfo($"\tSkipping '{fullPath}' because it is already embedded");
            return(resourceName);
        }

        if (compress)
        {
            resourceName = $"{prefix}{Path.GetFileName(fullPath).ToLowerInvariant()}.compressed";
        }

        LogInfo($"\tEmbedding '{fullPath}'");

        var checksum     = CalculateChecksum(fullPath);
        var cacheFile    = Path.Combine(cachePath, $"{checksum}.{resourceName}");
        var memoryStream = new MemoryStream();

        if (File.Exists(cacheFile))
        {
            using (var fileStream = File.Open(cacheFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                fileStream.CopyTo(memoryStream);
            }
        }
        else
        {
            using (var cacheFileStream = File.Open(cacheFile, FileMode.CreateNew, FileAccess.Write, FileShare.Read))
            {
                using (var fileStream = File.Open(fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    if (compress)
                    {
                        using (var compressedStream = new DeflateStream(memoryStream, CompressionMode.Compress, true))
                        {
                            fileStream.CopyTo(compressedStream);
                        }
                    }
                    else
                    {
                        fileStream.CopyTo(memoryStream);
                    }
                }
                memoryStream.Position = 0;
                memoryStream.CopyTo(cacheFileStream);
            }
        }
        memoryStream.Position = 0;
        streams.Add(memoryStream);
        var resource = new EmbeddedResource(resourceName, ManifestResourceAttributes.Private, memoryStream);

        ModuleDefinition.Resources.Add(resource);

        ReferenceCopyLocalPaths.RemoveAll(item => string.Equals(item, fullPath, StringComparison.OrdinalIgnoreCase));

        return(resourceName);
    }
예제 #3
0
파일: WeavingTask.cs 프로젝트: merbla/Fody
        public override bool Execute()
        {
            var referenceCopyLocalPaths = new List <string>();

            if (ReferenceCopyLocalPaths != null)
            {
                referenceCopyLocalPaths = ReferenceCopyLocalPaths.Select(x => x.ItemSpec).ToList();
            }
            var defineConstants = new List <string>();

            if (DefineConstants != null)
            {
                defineConstants = DefineConstants.Split(';').ToList();
            }
            return(new Processor
            {
                AssemblyFilePath = AssemblyPath,
                IntermediateDirectoryPath = IntermediateDir,
                KeyFilePath = KeyFilePath,
                SignAssembly = SignAssembly,
                ProjectDirectory = ProjectDirectory,
                References = References,
                SolutionDirectoryPath = SolutionDir,
                BuildEngine = BuildEngine,
                ReferenceCopyLocalPaths = referenceCopyLocalPaths,
                DefineConstants = defineConstants
            }.Execute());
        }
예제 #4
0
    public override void Execute()
    {
        var intermediateFolder = Path.GetDirectoryName(ModuleDefinition.FileName);
        var additionalFilePath = Path.Combine(intermediateFolder, "SomeExtraFile.txt");

        File.WriteAllText(additionalFilePath, DateTime.Now.ToString(CultureInfo.InvariantCulture));
        ReferenceCopyLocalPaths.Add(additionalFilePath);

        var customAttributes = ModuleDefinition.Assembly.CustomAttributes;

        var sampleAttr = customAttributes.FirstOrDefault(attr => attr.AttributeType.Name == "SampleAttribute");

        if (sampleAttr != null)
        {
            customAttributes.Remove(sampleAttr);
            var filePath = sampleAttr.AttributeType.Resolve().Module.FileName;

            ReferenceCopyLocalPaths.Remove(filePath);
            ReferenceCopyLocalPaths.Remove(Path.ChangeExtension(filePath, ".pdb"));
            ReferenceCopyLocalPaths.Remove(Path.ChangeExtension(filePath, ".xml"));

            // Do not use ShouldCleanReference in order to test the above code
            var assemblyRef = ModuleDefinition.AssemblyReferences.FirstOrDefault(i => i.Name == "SampleWeaver");
            if (assemblyRef != null)
            {
                ModuleDefinition.AssemblyReferences.Remove(assemblyRef);
            }
        }
    }
예제 #5
0
        private void RemoveLibReference(ModuleWeavingContext context)
        {
            var libRef = ModuleDefinition.AssemblyReferences.FirstOrDefault(i => i.IsInlineILAssembly());

            if (libRef == null)
            {
                return;
            }

            var importScopes = new HashSet <ImportDebugInformation>();

            foreach (var method in ModuleDefinition.GetTypes().SelectMany(t => t.Methods))
            {
                foreach (var scope in method.DebugInformation.GetScopes())
                {
                    ProcessScope(scope);
                }
            }

            ModuleDefinition.AssemblyReferences.Remove(libRef);

            var copyLocalFilesToRemove = new HashSet <string>(StringComparer.OrdinalIgnoreCase)
            {
                libRef.Name + ".dll",
                libRef.Name + ".xml",
                libRef.Name + ".pdb" // We don't ship this, but future-proof that ;)
            };

            ReferenceCopyLocalPaths.RemoveAll(i => copyLocalFilesToRemove.Contains(Path.GetFileName(i)));

            _log.Debug("Removed reference to InlineIL");

            void ProcessScope(ScopeDebugInformation scope)
            {
                ProcessImportScope(scope.Import);

                if (scope.HasScopes)
                {
                    foreach (var childScope in scope.Scopes)
                    {
                        ProcessScope(childScope);
                    }
                }
            }

            void ProcessImportScope(ImportDebugInformation importScope)
            {
                if (importScope == null || !importScopes.Add(importScope))
                {
                    return;
                }

                importScope.Targets.RemoveWhere(t => t.AssemblyReference.IsInlineILAssembly() || t.Type.IsInlineILTypeUsage(context));
                ProcessImportScope(importScope.Parent);
            }
        }
예제 #6
0
    public override void Execute()
    {
        ValidateSymbols();

        var type          = new TypeDefinition("SampleWeaverTest", "Configuration", TypeAttributes.Class | TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.AutoClass | TypeAttributes.AnsiClass, TypeSystem.ObjectReference);
        var contentField  = new FieldDefinition("Content", FieldAttributes.Public | FieldAttributes.Static, TypeSystem.StringReference);
        var propertyField = new FieldDefinition("PropertyValue", FieldAttributes.Public | FieldAttributes.Static, TypeSystem.StringReference);
        var method        = new MethodDefinition(".cctor", MethodAttributes.Static | MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName, TypeSystem.VoidReference);

        var instructions = method.Body.Instructions;

        instructions.Add(Instruction.Create(OpCodes.Ldstr, Config?.ToString() ?? "Missing"));
        instructions.Add(Instruction.Create(OpCodes.Stsfld, contentField));
        instructions.Add(Instruction.Create(OpCodes.Ldstr, Config?.Attribute("MyProperty")?.Value ?? "Missing"));
        instructions.Add(Instruction.Create(OpCodes.Stsfld, propertyField));
        instructions.Add(Instruction.Create(OpCodes.Ret));

        type.Fields.Add(contentField);
        type.Fields.Add(propertyField);
        type.Methods.Add(method);
        ModuleDefinition.Types.Add(type);

        var intermediateFolder = Path.GetDirectoryName(ModuleDefinition.FileName);
        var additionalFilePath = Path.Combine(intermediateFolder, "SomeExtraFile.txt");

        File.WriteAllText(additionalFilePath, DateTime.Now.ToString(CultureInfo.InvariantCulture));
        ReferenceCopyLocalPaths.Add(additionalFilePath);

        var customAttributes = ModuleDefinition.Assembly.CustomAttributes;

        var sampleAttr = customAttributes.FirstOrDefault(attr => attr.AttributeType.Name == "SampleAttribute");

        if (sampleAttr == null)
        {
            return;
        }

        customAttributes.Remove(sampleAttr);
        var filePath = sampleAttr.AttributeType.Resolve().Module.FileName;

        ReferenceCopyLocalPaths.Remove(filePath);
        ReferenceCopyLocalPaths.Remove(Path.ChangeExtension(filePath, ".pdb"));
        ReferenceCopyLocalPaths.Remove(Path.ChangeExtension(filePath, ".xml"));

        // Do not use ShouldCleanReference in order to test the above code
        var assemblyRef = ModuleDefinition.AssemblyReferences.FirstOrDefault(i => i.Name == "SampleWeaver");

        if (assemblyRef != null)
        {
            ModuleDefinition.AssemblyReferences.Remove(assemblyRef);
        }
    }
예제 #7
0
    private void InnerEmbed(string prefix, string fullPath, bool compress, bool addChecksum, bool disableCleanup)
    {
        if (!disableCleanup)
        {
            // in any case we can remove this from the copy local paths, because either it's already embedded, or it will be embedded.
            ReferenceCopyLocalPaths.RemoveAll(item => string.Equals(item, fullPath, StringComparison.OrdinalIgnoreCase));
        }

        var resourceName = $"{prefix}{Path.GetFileName(fullPath).ToLowerInvariant()}";

        if (ModuleDefinition.Resources.Any(x => string.Equals(x.Name, resourceName, StringComparison.OrdinalIgnoreCase)))
        {
            // - an assembly that is already embedded uncompressed, using <EmbeddedResource> in the project file
            // - if compress == false: an assembly that appeared twice in the ReferenceCopyLocalPaths, e.g. the same library from different nuget packages (https://github.com/Fody/Costura/issues/332)
            if (addChecksum && !checksums.ContainsKey(resourceName))
            {
                checksums.Add(resourceName, CalculateChecksum(fullPath));
            }

            LogDebug($"\tSkipping '{fullPath}' because it is already embedded");
            return;
        }

        if (compress)
        {
            resourceName += ".compressed";

            if (ModuleDefinition.Resources.Any(x => string.Equals(x.Name, resourceName, StringComparison.OrdinalIgnoreCase)))
            {
                // an assembly that appeared twice in the ReferenceCopyLocalPaths, e.g. the same library from different nuget packages (https://github.com/Fody/Costura/issues/332)
                LogDebug($"\tSkipping '{fullPath}' because it is already embedded");
                return;
            }
        }

        LogDebug($"\tEmbedding '{fullPath}'");

        var checksum     = CalculateChecksum(fullPath);
        var cacheFile    = Path.Combine(cachePath, $"{checksum}.{resourceName}");
        var memoryStream = BuildMemoryStream(fullPath, compress, cacheFile);

        streams.Add(memoryStream);
        var resource = new EmbeddedResource(resourceName, ManifestResourceAttributes.Private, memoryStream);

        ModuleDefinition.Resources.Add(resource);

        if (addChecksum)
        {
            checksums.Add(resourceName, checksum);
        }
    }
예제 #8
0
        public override void Execute()
        {
#if DEBUG && LAUNCH_DEBUGGER
            System.Diagnostics.Debugger.Launch();
#endif

            var includeAssemblies = BuildRegex(ReadConfigValue("IncludeAssemblies", string.Empty));
            var excludeAssemblies = BuildRegex(ReadConfigValue("ExcludeAssemblies", string.Empty));
            var includeResources  = BuildRegex(ReadConfigValue("IncludeResources", string.Empty));
            var excludeResources  = BuildRegex(ReadConfigValue("ExcludeResources", string.Empty));
            var hideImportedTypes = ReadConfigValue("HideImportedTypes", true);
            var namespacePrefix   = ReadConfigValue("NamespacePrefix", string.Empty);
            var compactMode       = ReadConfigValue("CompactMode", false);
            var fullImport        = ReadConfigValue("FullImport", false);

            var isDotNetCore = ModuleDefinition.IsTargetFrameworkDotNetCore();

            var references = isDotNetCore ? (IList <string>)References.Split(';') : ReferenceCopyLocalPaths;

            var codeImporter = new CodeImporter(ModuleDefinition)
            {
                ModuleResolver     = new LocalReferenceModuleResolver(this, references, includeAssemblies, excludeAssemblies),
                HideImportedTypes  = hideImportedTypes,
                NamespaceDecorator = name => namespacePrefix + name,
                CompactMode        = compactMode && !fullImport,
            };

            codeImporter.ILMerge();

            var importedModules = codeImporter.ListImportedModules();

            if (fullImport)
            {
                importedModules = ImportRemainingTypes(importedModules, codeImporter);
            }

            ValidateBamlReferences(ModuleDefinition, importedModules);

            ImportResources(ModuleDefinition, importedModules, includeResources, excludeResources, this);

            var importedReferences = new HashSet <string>(importedModules.Select(moduleDefinition => Path.GetFileNameWithoutExtension(moduleDefinition.FileName)), StringComparer.OrdinalIgnoreCase);

            bool IsImportedReference(string path)
            {
                return(importedReferences.Contains(Path.GetFileNameWithoutExtension(path)));
            }

            ReferenceCopyLocalPaths.RemoveAll(IsImportedReference);
            RuntimeCopyLocalPaths.RemoveAll(IsImportedReference);
        }
예제 #9
0
파일: dnMergeTask.cs 프로젝트: CCob/dnMerge
 private void ProcessAssembly(ModuleDefMD module)
 {
     ReferenceCopyLocalPaths
     .Select(x => x.ItemSpec)
     .Where(referenceCopyLocalFile => !MergeConfig.ExcludeReferences.Select(v => v.ToLower()).Any(excludedRef => referenceCopyLocalFile.ToLower().EndsWith(excludedRef))).ToList()
     .ForEach(referenceCopyLocalFile => {
         if (referenceCopyLocalFile.ToLower().EndsWith(".dll"))
         {
             try {
                 var referenceAssemblyData = File.ReadAllBytes(referenceCopyLocalFile);
                 var refModule             = ModuleDefMD.Load(referenceAssemblyData);
                 module.Resources.Add(new EmbeddedResource(refModule.Assembly.Name.ToLower(), SevenZipHelper.Compress(referenceAssemblyData)));
                 Logger.LogMessage($"Merged assembly {referenceCopyLocalFile}");
             } catch (Exception e) {
                 Log.LogMessage(MessageImportance.High, $"Failed to merge assembly {referenceCopyLocalFile} with error {e.Message}");
             }
         }
     });
 }
예제 #10
0
        public override void Execute()
        {
            // Debugger.Launch();

            var assemblyReferences = AssemblyReferences;
            // ReSharper disable once PossibleNullReferenceException

            const string JetBrainsAnnotations = "JetBrains.Annotations";

            var jetbrainsAnnotationsReference = assemblyReferences.FirstOrDefault(x => x.Name.StartsWith(JetBrainsAnnotations));

            if (jetbrainsAnnotationsReference == null)
            {
                LogWarning("Reference to JetBrains.Annotations not found.");
                return;
            }

            if (string.IsNullOrEmpty(ProjectDirectoryPath) || !Directory.Exists(ProjectDirectoryPath))
            {
                LogError("ProjectDirectoryPath is not a valid directory: " + ProjectDirectoryPath);
                return;
            }

            assemblyReferences.Remove(jetbrainsAnnotationsReference);
            ReferenceCopyLocalPaths.RemoveAll(file => string.Equals(JetBrainsAnnotations, Path.GetFileNameWithoutExtension(file), StringComparison.OrdinalIgnoreCase));

            var jetbrainsAnnotations = ModuleDefinition.AssemblyResolver.Resolve(jetbrainsAnnotationsReference);

            Debug.Assert(jetbrainsAnnotations != null, "jetbrainsAnnotations != null");
            var elements = new Executor(ModuleDefinition, jetbrainsAnnotations).Execute();

            Save(elements);

            if (!string.IsNullOrEmpty(DocumentationFilePath) && File.Exists(DocumentationFilePath))
            {
                XmlDocumentation.Decorate(DocumentationFilePath, elements);
            }
        }
        private void SignAllAssemblies()
        {
            // If this is renamed also fix the reference in the cleanup task in Das.StrongNameSigner.targets
            var signedAssemblyDirectory      = Path.Combine(OutputPath.ItemSpec, "DaS.StrongNameSigner");
            var copyLocalReferencesDirectory = Path.Combine(signedAssemblyDirectory, "copyLocalReferences");
            var referencesDirectory          = Path.Combine(signedAssemblyDirectory, "references");

            CreateDirectoryIfNotExists(signedAssemblyDirectory);
            CreateDirectoryIfNotExists(copyLocalReferencesDirectory);
            CreateDirectoryIfNotExists(referencesDirectory);

            _publicKeyData = GetPublicKeyData();
            _probingPaths  = References.Union(ReferenceCopyLocalPaths)
                             .Select(reference => Path.GetDirectoryName(reference.ItemSpec))
                             .ToImmutableList();
            _assemblyResolver = GetAssemblyResolver();

            SignedReferenceCopyLocalPaths = ReferenceCopyLocalPaths
                                            .Select(reference => SignAssembly(copyLocalReferencesDirectory, reference))
                                            .ToArray();
            SignedReferences = References
                               .Select(reference => SignAssembly(referencesDirectory, reference))
                               .ToArray();
        }
예제 #12
0
    private void EmbedResources(Configuration config)
    {
        if (ReferenceCopyLocalPaths == null)
        {
            throw new WeavingException("ReferenceCopyLocalPaths is required you may need to update to the latest version of Fody.");
        }

        cachePath = Path.Combine(Path.GetDirectoryName(AssemblyFilePath), "Costura");
        if (!Directory.Exists(cachePath))
        {
            Directory.CreateDirectory(cachePath);
        }

        var onlyBinaries = ReferenceCopyLocalPaths.Where(x => x.EndsWith(".dll") || x.EndsWith(".exe"));

        foreach (var dependency in GetFilteredReferences(onlyBinaries, config))
        {
            var fullPath = Path.GetFullPath(dependency);

            string resourceName;

            if (dependency.EndsWith(".resources.dll"))
            {
                resourceName = Embed(string.Format("costura.{0}.", Path.GetFileName(Path.GetDirectoryName(fullPath))), fullPath, !config.DisableCompression);
                if (config.CreateTemporaryAssemblies)
                {
                    checksums.Add(resourceName, CalculateChecksum(fullPath));
                }
                continue;
            }

            resourceName = Embed("costura.", fullPath, !config.DisableCompression);
            if (config.CreateTemporaryAssemblies)
            {
                checksums.Add(resourceName, CalculateChecksum(fullPath));
            }
            if (!config.IncludeDebugSymbols)
            {
                continue;
            }
            var pdbFullPath = Path.ChangeExtension(fullPath, "pdb");
            if (File.Exists(pdbFullPath))
            {
                resourceName = Embed("costura.", pdbFullPath, !config.DisableCompression);
                if (config.CreateTemporaryAssemblies)
                {
                    checksums.Add(resourceName, CalculateChecksum(pdbFullPath));
                }
            }
        }

        foreach (var dependency in onlyBinaries)
        {
            var prefix = "";

            if (config.Unmanaged32Assemblies.Any(x => x == Path.GetFileNameWithoutExtension(dependency)))
            {
                prefix       = "costura32.";
                hasUnmanaged = true;
            }
            if (config.Unmanaged64Assemblies.Any(x => x == Path.GetFileNameWithoutExtension(dependency)))
            {
                prefix       = "costura64.";
                hasUnmanaged = true;
            }

            if (String.IsNullOrEmpty(prefix))
            {
                continue;
            }

            var fullPath     = Path.GetFullPath(dependency);
            var resourceName = Embed(prefix, fullPath, config.DisableCompression);
            checksums.Add(resourceName, CalculateChecksum(fullPath));
            if (!config.IncludeDebugSymbols)
            {
                continue;
            }
            var pdbFullPath = Path.ChangeExtension(fullPath, "pdb");
            if (File.Exists(pdbFullPath))
            {
                resourceName = Embed(prefix, pdbFullPath, config.DisableCompression);
                checksums.Add(resourceName, CalculateChecksum(pdbFullPath));
            }
        }
    }
예제 #13
0
    void Embed(string prefix, string fullPath, bool compress, bool addChecksum)
    {
        // in any case we can remove this from the copy local paths, because either it's already embedded, or it will be embedded.
        ReferenceCopyLocalPaths.RemoveAll(item => string.Equals(item, fullPath, StringComparison.OrdinalIgnoreCase));

        var resourceName = $"{prefix}{Path.GetFileName(fullPath).ToLowerInvariant()}";

        if (ModuleDefinition.Resources.Any(x => string.Equals(x.Name, resourceName, StringComparison.OrdinalIgnoreCase)))
        {
            // - an assembly that is already embedded uncompressed, using <EmbeddedResource> in the project file
            // - if compress == false: an assembly that appeared twice in the ReferenceCopyLocalPaths, e.g. the same library from different nuget packages (https://github.com/Fody/Costura/issues/332)
            if (addChecksum && !checksums.ContainsKey(resourceName))
            {
                checksums.Add(resourceName, CalculateChecksum(fullPath));
            }

            LogInfo($"\tSkipping '{fullPath}' because it is already embedded");
            return;
        }

        if (compress)
        {
            resourceName += ".compressed";

            if (ModuleDefinition.Resources.Any(x => string.Equals(x.Name, resourceName, StringComparison.OrdinalIgnoreCase)))
            {
                // an assembly that appeared twice in the ReferenceCopyLocalPaths, e.g. the same library from different nuget packages (https://github.com/Fody/Costura/issues/332)
                LogInfo($"\tSkipping '{fullPath}' because it is already embedded");
                return;
            }
        }

        LogInfo($"\tEmbedding '{fullPath}'");

        var checksum     = CalculateChecksum(fullPath);
        var cacheFile    = Path.Combine(cachePath, $"{checksum}.{resourceName}");
        var memoryStream = new MemoryStream();

        if (File.Exists(cacheFile))
        {
            using (var fileStream = File.Open(cacheFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                fileStream.CopyTo(memoryStream);
            }
        }
        else
        {
            using (var cacheFileStream = File.Open(cacheFile, FileMode.CreateNew, FileAccess.Write, FileShare.Read))
            {
                using (var fileStream = File.Open(fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    if (compress)
                    {
                        using (var compressedStream = new DeflateStream(memoryStream, CompressionMode.Compress, true))
                        {
                            fileStream.CopyTo(compressedStream);
                        }
                    }
                    else
                    {
                        fileStream.CopyTo(memoryStream);
                    }
                }
                memoryStream.Position = 0;
                memoryStream.CopyTo(cacheFileStream);
            }
        }

        memoryStream.Position = 0;
        streams.Add(memoryStream);
        var resource = new EmbeddedResource(resourceName, ManifestResourceAttributes.Private, memoryStream);

        ModuleDefinition.Resources.Add(resource);

        if (addChecksum)
        {
            checksums.Add(resourceName, checksum);
        }
    }
예제 #14
0
    void EmbedResources(Configuration config)
    {
        if (ReferenceCopyLocalPaths == null)
        {
            throw new WeavingException("ReferenceCopyLocalPaths is required you may need to update to the latest version of Fody.");
        }

        cachePath = 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);
                    continue;
                }
            }

            Embed("costura.", fullPath, !disableCompression, createTemporaryAssemblies);

            if (!config.IncludeDebugSymbols)
            {
                continue;
            }
            var pdbFullPath = Path.ChangeExtension(fullPath, "pdb");
            if (File.Exists(pdbFullPath))
            {
                Embed("costura.", pdbFullPath, !disableCompression, createTemporaryAssemblies);
            }
        }

        foreach (var dependency in onlyBinaries)
        {
            var prefix = "";

            if (config.Unmanaged32Assemblies.Any(x => string.Equals(x, Path.GetFileNameWithoutExtension(dependency), StringComparison.OrdinalIgnoreCase)))
            {
                prefix       = "costura32.";
                hasUnmanaged = true;
            }
            if (config.Unmanaged64Assemblies.Any(x => string.Equals(x, Path.GetFileNameWithoutExtension(dependency), StringComparison.OrdinalIgnoreCase)))
            {
                prefix       = "costura64.";
                hasUnmanaged = true;
            }

            if (string.IsNullOrEmpty(prefix))
            {
                continue;
            }

            var fullPath = Path.GetFullPath(dependency);
            Embed(prefix, fullPath, !disableCompression, true);

            if (!config.IncludeDebugSymbols)
            {
                continue;
            }
            var pdbFullPath = Path.ChangeExtension(fullPath, "pdb");
            if (File.Exists(pdbFullPath))
            {
                Embed(prefix, pdbFullPath, !disableCompression, true);
            }
        }
    }
예제 #15
0
    private EmbeddedReferenceInfo InnerEmbed(string prefix, string relativePath, string fullPath, bool compress, bool addChecksum, bool disableCleanup)
    {
        if (!disableCleanup)
        {
            // in any case we can remove this from the copy local paths, because either it's already embedded, or it will be embedded.
            ReferenceCopyLocalPaths.RemoveAll(item => string.Equals(item, fullPath, StringComparison.OrdinalIgnoreCase));
        }

        var resourceName = $"{prefix}{Path.GetFileName(fullPath).ToLowerInvariant()}";

        if (ModuleDefinition.Resources.Any(x => string.Equals(x.Name, resourceName, StringComparison.OrdinalIgnoreCase)))
        {
            // - an assembly that is already embedded uncompressed, using <EmbeddedResource> in the project file
            // - if compress == false: an assembly that appeared twice in the ReferenceCopyLocalPaths, e.g. the same library from different nuget packages (https://github.com/Fody/Costura/issues/332)
            if (addChecksum && !_checksums.ContainsKey(resourceName))
            {
                _checksums.Add(resourceName, CalculateSha1Checksum(fullPath));
            }

            WriteDebug($"\t\tSkipping '{fullPath}' because it is already embedded");
            return(null);
        }

        if (compress)
        {
            resourceName += ".compressed";

            if (ModuleDefinition.Resources.Any(x => string.Equals(x.Name, resourceName, StringComparison.OrdinalIgnoreCase)))
            {
                // an assembly that appeared twice in the ReferenceCopyLocalPaths, e.g. the same library from different nuget packages (https://github.com/Fody/Costura/issues/332)
                WriteDebug($"\t\tSkipping '{fullPath}' because it is already embedded");
                return(null);
            }
        }

        WriteInfo($"\t\tEmbedding '{fullPath}'");

        var sha1Checksum = CalculateSha1Checksum(fullPath);
        var cacheFile    = Path.Combine(_cachePath, $"{sha1Checksum}.{resourceName}");
        var memoryStream = BuildMemoryStream(fullPath, compress, cacheFile);

        _streams.Add(memoryStream);
        var resource = new EmbeddedResource(resourceName, ManifestResourceAttributes.Private, memoryStream);

        ModuleDefinition.Resources.Add(resource);

        if (addChecksum)
        {
            _checksums.Add(resourceName, sha1Checksum);
        }

        var          version      = string.Empty;
        AssemblyName assemblyName = null;

        if (relativePath.ToLower().EndsWith(".dll"))
        {
            try
            {
                var versionInfo = FileVersionInfo.GetVersionInfo(fullPath);
                version = versionInfo.FileVersion;

                assemblyName = AssemblyName.GetAssemblyName(fullPath);
            }
            catch (Exception)
            {
                // Native assemblies don't have assembly names
            }
        }

        return(new EmbeddedReferenceInfo
        {
            ResourceName = resourceName,
            Version = assemblyName?.Version.ToString(4) ?? version,
            AssemblyName = assemblyName?.FullName ?? string.Empty,
            RelativeFileName = relativePath,
            Sha1Checksum = sha1Checksum,
            Size = new FileInfo(fullPath).Length
        });
    }