Exemplo n.º 1
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);
    }
Exemplo n.º 2
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);
            }
        }
Exemplo n.º 3
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);
        }
    }
Exemplo n.º 4
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);
        }
Exemplo n.º 5
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);
            }
        }
Exemplo n.º 6
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);
        }
    }
Exemplo n.º 7
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
        });
    }