Reputation: 1155
is it possible to inject resources into .net applications (after compilation) so they can be used by the application via resource streams ?
I've read that .net resources differ from regular winapi .exe resources. Is that true ?
I know the tool "resource hacker", it can inject pretty much anything into an exe ( as far as I know), but I'm not sure about .net files. (at, work, can't test it right now).
Upvotes: 0
Views: 1828
Reputation: 3150
If the template code for your self-extracting exe is simple enough, I would suggest embedding it as a resource in the application that you initially intended to write (the one that you wanted to use to do the resource manipulation).
That way, you can use a combination of C#'s CodeDomProvider and ResourceWriter to produce a self-contained exe file with your desired resources baked in.
Basically, the flow is like so:
Main(string args[])
method of your program in text format)CodeDomProvider
and call CompileAssemblyFromSource
with parameters that specify the resource stream you created in the prior stepEdit: Here is a working example. It embeds the string
Hello World! (from a file as a byte[]
to show you can use this concept with "binary resource" data) into a console application:
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);
}
}
}
}
Upvotes: 4