Link to home
Start Free TrialLog in
Avatar of jazzIIIlove
jazzIIIloveFlag for Sweden

asked on

How to "embedd" my exe file to another program of mine.

Hi there;

I  want to embed an exe of mine into another of my project. When I want to add the file as "Add reference"->Browse->my.exe

.NET give the following erro: A reference to %myexepath% could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component.

I want to ask what I should do? Is it impossible to embed my executable?
You may comment to call the process, not embed but I really want to embed it.

I am using VS 2008 but if it is possible I can switch to VS 2010 for this.

Best regards.
Avatar of Anwar Saiah
Anwar Saiah

I think you first need to assemble it !
Use an assembly editor, look in google.
Avatar of jazzIIIlove

ASKER

Prior to assemblying it, I find this, there is a solution file but it skips the line:
if (resourceName.EndsWith(".exe")) {
On the other hand:
Should I compile that assembly file I created?

Best regards.

I presume you want to store the .exe file into your program and extract and run it later. if that is what you are looking for then, you can add your .exe file as an embedeed resource and then extract it later...

To add .exe file as resource, right click on project Add -> existing item and select your .exe file and then in the Properties window of this added file, Set Build Action = Embedded Resource.

Later when you want extract this .exe file from resource to a folder (and possibly to run it),  check out the code in this EE answer => https://www.experts-exchange.com/questions/25002933/extracting-an-exe-file-from-resource.html

Code from this link below:

string includeFileName = "Sample.exe";
string strNewPathToSave = @"C:\MyNewPath\Sample.exe";

System.IO.Stream myFile = System.Reflection.Assembly.GetManifestResourceStre am(includeFileName);

if ( myFile== null )
   return "Unable to read the file."; 

System.IO.FileStream fs = System.IO.File.OpenWrite(strNewPathToSave);
try
 {
    // Save the File...
    byte[] buffer = new byte[myFile.Length];
    myFile.Read(buffer,0,(int)myFile.Length);
    fs.Write(buffer,0,buffer.Length);
  }
finally
{
   fs.Close();
}

Open in new window

No you should add it to your project as assembly and then just compile the whole package.
Hi guys;

kris_per:
ok, I got the point. Let me tell my aim:
I want to call the exe inside of my program, that means, I have no intention to store my executable after I create a setup for my main program (at least, I hope so).
So, is it compulsory to read the executable? I mean can 't I just call the exe without the exe after installation? (embedded to my main program)

aboo_s:
>>No you should add it to your project as assembly and then just compile the whole package.
Ok, I got the assembly but should I compile the assembly prior putting it to my main program? or not.

I will try both comments.

Best regards.
kris_per:
I mean why am i reading and writing the executable?

OK. If you have a setup and you can include the files into the setup, then that is good..when installing, setup will install the files (your main program and the second.exe) to a folder and your program can run the second.exe by using System.Diagnostics.Process.Start method. This is the clean solution...In this case you dont need to embedd the second.exe inside your program...
ASKER CERTIFIED SOLUTION
Avatar of kris_per
kris_per

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
kris_per:
>>OK. If you have a setup and you can include the files into the setup, then that is good..when >>installing, setup will install the files (your main program and the second.exe) to a folder and your >>program can run the second.exe by using System.Diagnostics.Process.Start method.
I am aware but as in the question, I have no intention to have my exe in the setup folder.

I need to dirt my hand:)

So, is it necessary to read and save the executable? Will it run with this way, e.g. when I click a button in my main program?

aboo_s:
I am waiting for the response whether I need to compile the asm or not. Moreover, after compilation or not, how can I reference the asm in my original code?

Best regards.

>I mean can 't I just call the exe without the exe after installation?

I hope by 'call the exe' you mean, start running that exe. after installation of the both the files (your main program and the exe), you can launch the exe using Process.Start method...
>>I have no intention to have my exe in the setup folder.

As I said, .exe assemblies can not be referenced for using a class/methods in them. You can just start them from a folder (like if you have app.exe file in a folder, you double-click on it to start it). So you need to have the exe file in some folder...If you dont want that exe permenantly in the folder (as setup will do), then you need to keep it hidden somewhere...one such option is to keep the .exe file as a resource within your main program exe itself. i.e. your main program exe file embedding the second exe file inside it. so when you need to use the second exe, you extract from resource to a folder and start it...to start the exe you got to have it in a folder...

A correction in my previous comment: actually exe assemblies can be added as reference in VS 2008...
>> your main program exe file embedding the second exe file inside it. so when you need to use the >>second exe, you extract from resource to a folder and start it...to start the exe you got to have it in a >>folder...

ok, I try for the above code but I fail in the line:
System.IO.Stream myFile = System.Reflection.Assembly.GetManifestResourceStream(includeFileName);
There is no GetManifestResourceStream function. What should I do?

Btw, I still don't get why I am writing the file, I mean it seems to execute the file, I need to extract it to another location in the machine.
Note that:
 >>To add .exe file as resource, right click on project Add -> existing item and select your .exe >>file >>and then in the Properties window of this added file, Set Build Action = Embedded Resource.
I have applied the above step.

Regards.
>>A correction in my previous comment: actually exe assemblies can be added as reference in VS >>2008...
Ok, but should I compile the assembly code? How to reference the file in the code? Any example code regarding this?

Best regards.

When you add an exe assembly as a reference, in Properties window of this reference is by default Copy Local is True which means it will be copied to your bin/debug folder; so when you run your program this exe will be available for your main program...that is the standard behaviour...

But this exe file need not to be there when your program starts; but it needs to be there in the folder when you actually use it (for example clicking a button uses a class from that exe)

ok..some sample follows in the next comment...hold on...

Say you have Apple.exe assembly file in a folder c:\apple and it has a public class named 'MyApple' in namespace 'AppleNS'

now in your project, right click on References -> Add Reference -> Browse to c:\app1 folder and select one.exe.

In one of .cs file in your project, add the line 'Using AppleNS;' at the top.
Then in one of the methods (say buttonProcess_Click method) in that .cs file you create MyApple object like

MyApple ma = new MyApple();
// now use the members of ma.

Build your project. Since 'Copy Local' is True by default for this added reference, building your project will copy Apple.exe file to your project's bin/debug folder...
Now the bin/debug will have your projects exe file and Apple.exe file as well.

When you deploy your project using a setup, by default both the exe files will be installed; that's the standard behaviour.

Apple.exe file need not to be in the folder when your program starts; but it needs to be there in the folder when you actually use it (ie when buttonProcess_Click  is called).

Now if you dont this Apple.exe file to be in the folder, then you remove it from the setup first; then one of the options is to carry the Apple.exe again as embedded resource; doing this is mentioned in my first comment...

so though you have added it as a reference to use it in the code; you have to add it again as a resource to carry the assembly file and then in buttonProcess_Click   method:
{
ExtractAppleExe(); // code for this method in my first comment
// then
MyApple ma = new MyApple();
// now use the members of ma.
// delete the extracted exe file
}

Hope this summarizes everything...Let me know if you need more clarification...

jazzIIIlove, I need to take off now...so i may not reply immediately now...i will reply later...
>>now in your project, right click on References -> Add Reference -> Browse to c:\app1 folder and >>select one.exe.
I got the error:
.NET give the following error: A reference to %myexepath% could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component.
I forgot to give the reference to my first comments, the code I used was:
http://www.cs.nyu.edu/~vs667/articles/embed_executable_tutorial/
My executable is not C# compatible, I coded it in Java and convert it to an executable.

Stream streamToResourceFile = GetType().Assembly.GetManifestResourceStream("appName.exeName.exe");

worked to copy the file to somewhere in my drive.

but my very question is:
Why am I copying it? Why can't I really embed it to my application? I mean I may read the file as binary then use some File.Copy function in C#. I don't see the point of this. Why can't I run it directly from C# code?

I think you will say after copying it [we did at last], use Process, then what is the point of doing this? I mean my aim is directly embedding and running it when I click the button. Any other comment for this?

Regards.
kris_per:
ok, let me give more code regarding this, below code ought to execute but it seems it doesn't work with my exe but first:

Could you explain this:
you wrote:
>>Say you have Apple.exe assembly file in a folder c:\apple and it has a public class named 'MyApple' >>in namespace 'AppleNS', then blabla.

So, if this isn't a Java application converted executable but an executable of a C#  , then would above  comment, ID: 33119918, be working?

I really want to do this but I only managed to copy the executable.

So, are we going to end up with aboo_s comment?
What am i asking is that I tried for IDA pro for my executable and have an asm file? Should I compile it in fasm or masm? In fact, I try but they both give errors which I couldn't solve. So, 1) is IDA Pro a good solution to extract asm? If not, which solution do you recommed? 2) Should I compile the extracted IDA? If so, which compiler do your recommend apart from masm and fasm?

Best regards.
public void rerun()
        {
            string filePath = null;
            string currentPath = System.Environment.CurrentDirectory + "\\";

            // search for exe files
            DirectoryInfo dir = new DirectoryInfo(currentPath);

            // retrieve the files info
            FileInfo[] files = dir.GetFiles("*.exe");
         
            
                // only one EXE file found
                filePath = currentPath + files[1].Name;


                FileStream fs = null;
                BinaryReader br = null;
                if (File.Exists(filePath))
                {
                    // read the bytes from the application exe file
                    fs = new FileStream(filePath, FileMode.Open);
                    br = new BinaryReader(fs);
                    byte[] bin = br.ReadBytes(Convert.ToInt32(fs.Length));
                    fs.Close();
                    br.Close();

                    // load the bytes into Assembly
                    Assembly a = Assembly.Load(bin);
                    // search for the Entry Point
                    MethodInfo method = a.EntryPoint;
                    if (method != null)
                    {
                        // create an istance of the Startup form Main method
                        object o = a.CreateInstance(method.Name);
                        // invoke the application starting point
                        method.Invoke(o, null);
                    }
                }
                fs.Close();
                br.Close();
            
        }

Open in new window

jazzIIIlove,

You can use only .NET assemblies in References. If your exe is not a .net assembly (like converted from java or in unmanaged c/c++) and when you add it in References, you will get the error message 'A reference to %myexepath% could not be added.' (I also get the same error when I tried to add a non .net exe to a project)

Using IDA pro like tools to get the .asm file (from a non .net exe file) and trying to use it as Reference in any form also would not work, as it is not in .net assembly format (manifest, metadata, etc).

As in your code, trying to read the exe data in byte array and using Assembly.Load(bin) also will not work if the exe is a non .net(unmanaged) exe. Assembly.Load fails with BadImageFormatException when I tried to load unmanaged exe.

Since this is unmanaged exe, I started to look in the unmanaged win32 apis to load the file and start the Entry point. LoadModule function can be used to load a file and then find the entrypoint (main or WinMain for the unmanaged exe format files) to start the program. But LoadModule loads only from a file in a folder and I could not easily find an api that takes a byte array to load.

Now to your questions like - Why am I copying it? Why can't I run it directly from C# code?. Well, again if it is a .net exe, then you can start it from the code using Assembly.Load, and then invoking the EntryPoint (as in your code). Since this is a java-developed exe, you can not start it directly from c# using Assembly.load or I am not sure about an win32 api to load it from bytes. So the remaining option is to copy it to a folder and use Process.Start.

Hope this helps.
 

:)
Very well explained. The question gets its tops. Now, get ready, I just did this. :)
with boxedapp aka software virtualization. How did they this is a great mystery for me right now but it's working. Any idea? How can they do this?

Best regards.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial