Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

include an EXE at compile time

Posted on 2004-10-27
11
Medium Priority
?
525 Views
Last Modified: 2013-11-18
Is is possible to include an exe as a binary resource at compiletime?
if so, How would I go about it. I have been using a program to generate an include (.cpp file), but it takes too long to compile like this.

thanks
0
Comment
Question by:cafechris
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 3
11 Comments
 
LVL 12

Expert Comment

by:andrewjb
ID: 12419864
Windows? Use a resource .rc file to include the .exe as a binary resource.... Something like..

1000      RCDATA  "..\TheFile.exe"

though you'll have to extract it and save to a temp. file somewhere before you can execute it.
0
 
LVL 12

Expert Comment

by:stefan73
ID: 12420499
Hi cafechris,
A more generic approach would be to generate code from your exe as part of a makefile, using a simple auxilliary C binary. Simple binary:

#include <stdio.h>
#include <stdlib.h>

int main (int argc,char** argv){
    size_t readlen;
    unsigned char buf[16];
    FILE* f;
    unsigned int i;

    if(argc!=3){
        fprintf(stderr,"Syntax: %s <varname> <input_file>\n",argv[0]);
        exit(2);
    }

    if(!(f=fopen(argv[2],"rb"))){
        fprintf(stderr,"Cannot open input file '%s'\n",argv[2]);
        exit(2);
    }
   
    printf("unsigned char %s[]={\n",argv[1]);
    while(0!=(readlen=fread(buf,1,sizeof(buf),f))){
        putchar('\t');
        for(i=0;i<readlen;i++)
            printf("0x%02x,",buf[i]);
        putchar('\n');
    }
    printf("};\n\n");
   
    fclose(f);
}

Then you can add to your makefile:



data.o: data.c
    $(CC) -c data.c

data.c: your_exe bin2c
    bin2c your_data_struct your_exe > data.c

bin2c: bin2c.c
    $(CC) bin2c.c -o bin2c



Cheers!

Stefan
0
 
LVL 1

Author Comment

by:cafechris
ID: 12425085
Sorry for not posting Microsoft Visual Studio c++ 6

stefan
thanks, but this is the method I have been using (if I understand you right). I have been creating an array just like yours, and then #including it into my code. Now, about the make file? I am using Microsofts visual studio vc++ 6 . I have never done anything with make files. Is this what I am missing?

andrewjb
>>1000      RCDATA  "..\TheFile.exe"
>>though you'll have to extract it and save to a temp. file somewhere before you can execute it.

this is probably more of what I am looking for. How do I extract it and save to temp? Thanks
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 12

Expert Comment

by:andrewjb
ID: 12425185
I use Delphi/Builder so there's a wrapper. But I think the API calls are FindResource() and LoadResource() etc if you look them up in help.

You 'just' load the resource from the ID you gave in the .rc (1000 in my example) then would have to save it somewhere to disk if you want to run it.
0
 
LVL 1

Author Comment

by:cafechris
ID: 12426189
I don't see how api calls could help here. I need this at compile time.

OK, This is basically what I need.
I need to store the data from my resource.exe into my program.exe. I want to be able to generate an exe from my program.exe that would be an exact copy of the resource.exe. To generate it from within my program.exe , I would create a file and write the binary recource data to it.  Hope I am being clear enough.

I adjusted the points from 50 --> 70. I don't mind going more as I see fit. Thanks so far.
0
 
LVL 12

Accepted Solution

by:
andrewjb earned 280 total points
ID: 12427534
??

Create a .rc file. Add it to your project. Include something like the RCDATA line I gave you above.
Compile your application. You've now got myprog.exe which contains otherprog.exe as a binary resource.
myprog.exe runs. Within it, you decide somewhere that you want to extract and run otherprog.exe
So you need to write a function within myprog that extracts the binary resource, copies it to a temporary file, runs it, then probably deletes the temporary file.
To extract it you call functions like FindResource() and LoadResource(). (These are calls to the Windows API. How else are you going to extract the stuff?)
You can create a temporary file using something like MakeTempFilename() - I can't remember the exact funciton call but I'm sure a quick search will locate it for you
Once you've Find/LoadResource you'll have a handle to a memory block. Write it to the temp file.
Execute the otherprog.exe using System() or some similar call.
Wait until it's finished. You might need WaitForSingleObject() or whatever the blocking call is called.
Delete the file.

I don't really have the time (or, for 50/70 points the inclination) to do a fully working example. I was just trying to point you in the right direction.

You need to pull the file _in_ at compile time (hence the .rc file) but extract it at run time (hence the API calls)
0
 
LVL 1

Author Comment

by:cafechris
ID: 12427803
Ok I will try it. I hope I can get to it today, if not , then tomorrow.
0
 
LVL 1

Author Comment

by:cafechris
ID: 12428690
I can't get it to work.
I must not understand how the rc files work. I havn't used them much.

Would it be worth it to you if I raised pts to 200. I don't mind if you give me an example of the rc and help me get a working example going.

here is what I have so far:

================================
generated .rc file and added this line
in EXE.rc ------------>
1000      RCDATA  "..\TheFile.exe"

================================
in resource.h ------->
#define IDI_EXE                       1000

================================
in .cpp -------------->
#include "res/resource.h"
#include "stdafx.h"
#include "stdio.h"

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
      HRSRC hRsrc = FindResource(NULL, MAKEINTRESOURCE( IDI_EXE ), RT_RCDATA/*"exe"*/);
             if(!hRsrc)
                                 MessageBox(0,"FindResource Failed",NULL,0);

               HGLOBAL hTemplate = LoadResource(NULL, hRsrc);
            if(!hTemplate)
             MessageBox(0,"LoadResource Failed",NULL,0);

/*here is where I will output binary exe data  ?????  somehow  ?????*/

      return 0;
}
0
 
LVL 1

Author Comment

by:cafechris
ID: 12430549
OK got it, I will post the results in a few minutes.
0
 
LVL 1

Author Comment

by:cafechris
ID: 12430643
================================
generated .rc file and added this line
in EXE.rc ------------>
IDI_EXE      RCDATA  DISCARDABLE  "E:\Programming\CPP\Win32\EmbedResourceEXE\Message\Release\Message.exe"
//make sure you place it before the   (#ifdef APSTUDIO_INVOKED... )

================================
in resource.h ------->
#define IDI_EXE                       1000

================================
#include "stdafx.h"
#include "stdio.h"
#include "res/resource.h"

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
      
      char *newFile = "RESOURCE.EXE";
       
      HRSRC hRsrc = FindResource(NULL, MAKEINTRESOURCE( IDI_EXE ), RT_RCDATA);
        if(!hRsrc)
                  MessageBox(0,"FindResource Failed",NULL,0);

      DWORD szRsrc = SizeofResource(NULL, hRsrc);

    HGLOBAL hglRsrc = LoadResource(NULL, hRsrc);
        if(!hglRsrc )
             MessageBox(0,"LoadResource Failed",NULL,0);

//get the first byte of the resource data LockResource()
      char *firstByte = (char *)LockResource(hglRsrc );

    FILE *f = NULL;

      if(!(f = fopen(newFile ,"wb")))
            return 0;
      fwrite(firstByte ,szRsrc,1,f);

      fclose(f);

                FreeResource( hglRsrc );

      return 0;
}

this is what workes for me,
I think you have to unload the resource, but I couldn't find anything on RCDATA types.
If you see anything wrong with my code please post. I am just an artist gone programmer, and I know my programming could use a bit of help.
0
 
LVL 1

Author Comment

by:cafechris
ID: 12430659
of course I should return if the handles are NULL....whoops.
Just replace messageBox... with return 0;
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article covers the basics of the Sass, which is a CSS extension language. You will learn about variables, mixins, and nesting.
Introduction Knockoutjs (Knockout) is a JavaScript framework (Model View ViewModel or MVVM framework).   The main ideology behind Knockout is to control from JavaScript how a page looks whilst creating an engaging user experience in the least …
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
HTML5 has deprecated a few of the older ways of showing media as well as offering up a new way to create games and animations. Audio, video, and canvas are just a few of the adjustments made between XHTML and HTML5. As we learned in our last micr…
Suggested Courses

636 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question