Link to home
Start Free TrialLog in
Avatar of chris rrr
chris rrrFlag for United States of America

asked on

include an EXE at compile time

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
Avatar of andrewjb
andrewjb
Flag of United Kingdom of Great Britain and Northern Ireland image

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.
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
Avatar of chris rrr

ASKER

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
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.
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.
ASKER CERTIFIED SOLUTION
Avatar of andrewjb
andrewjb
Flag of United Kingdom of Great Britain and Northern Ireland image

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
Ok I will try it. I hope I can get to it today, if not , then tomorrow.
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;
}
OK got it, I will post the results in a few minutes.
================================
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.
of course I should return if the handles are NULL....whoops.
Just replace messageBox... with return 0;