向.net可执行文件注入资源

本文关键字:资源 注入 可执行文件 net | 更新日期: 2023-09-27 18:19:00

是否有可能将资源注入到。net应用程序中(在编译之后),以便应用程序可以通过资源流使用它们?

我读到。net资源不同于常规的winapi .exe资源。是真的吗?

我知道这个工具"资源黑客",它可以注入几乎任何东西到一个exe(据我所知),但我不确定。net文件。

向.net可执行文件注入资源

如果您的自提取exe的模板代码足够简单,我建议将其作为资源嵌入到您最初打算编写的应用程序中(您想要使用它来进行资源操作)。

这样,你就可以结合使用c#的CodeDomProvider和ResourceWriter来生成一个包含你想要的资源的自包含的exe文件。

基本上,流程是这样的:

  • 从应用程序中提取"自提取可执行文件"的模板(作为资源文件嵌入-该文件以文本格式包含程序的Main(string args[])方法)
  • 将所需资源写入资源流
  • 创建CodeDomProvider并调用CompileAssemblyFromSource,参数指定您在上一步中创建的资源流

编辑:这里是一个工作示例。它嵌入了string Hello World!(从一个文件作为byte[],以表明您可以使用这个概念与"二进制资源"数据)到控制台应用程序:

using System;
using System.CodeDom.Compiler;
using System.Diagnostics;
using System.IO;
using System.Resources;
namespace DynamicEmbed
{
    class Program
    {
        static void Main(string[] args)
        {
            var parameters = new CompilerParameters
            {
                GenerateExecutable = true,
                OutputAssembly = Path.Combine(Environment.CurrentDirectory, Path.GetTempFileName()) + ".exe",
            };
            // Based on the code your template uses, these will need to change
            parameters.ReferencedAssemblies.Add("System.dll");
            parameters.ReferencedAssemblies.Add("System.Core.dll");
            parameters.ReferencedAssemblies.Add("System.Linq.dll");
            // Create the embedded resource file on disk
            string embeddedResourceFile = Path.GetTempFileName();
            using (var rw = new ResourceWriter(embeddedResourceFile))
            {
                var tempFile = Path.GetTempFileName();
                File.WriteAllText(tempFile, "Hello, World!");
                rw.AddResourceData("my.resource.key", "ResourceTypeCode.ByteArray", File.ReadAllBytes(tempFile));
            }
            // Embed the resource file into the exe
            parameters.EmbeddedResources.Add(embeddedResourceFile);
            // Source code for dynamically generated exe
            string source =
@"
using System;
using System.Linq;
using System.Resources;
namespace DynamicallyEmbeded
{
    class Program
    {
        static void Main(string[] args)
        {
            var resourceName = typeof(Program).Assembly.GetManifestResourceNames()[0];
            Console.WriteLine(""Embedded resource name: {0}"", resourceName);
            var stream = typeof(Program).Assembly.GetManifestResourceStream(resourceName);
            var resourceData = new byte[] { };
            using (var rr = new ResourceReader(stream))
            {
                var resourceType = """";
                rr.GetResourceData(""my.resource.key"", out resourceType, out resourceData);
            }
            var contents = new string(resourceData.Select(x => (char)x).ToArray());
            Console.WriteLine(""Embedded resource contents: {0}"", contents);
            Console.Write(""Press any key to continue . . ."");
            Console.ReadKey();
        }
    }
}";
            // Create the code
            CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
            var results = provider.CompileAssemblyFromSource(parameters, source);
            // Start the program (just to show it worked)
            if (results.Errors.Count == 0)
            {
                Process.Start(parameters.OutputAssembly);
            }
        }
    }
}