chris rrr
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
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
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(bu f,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
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(bu
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
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
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.
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.
ASKER
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.
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Ok I will try it. I hope I can get to it today, if not , then tomorrow.
ASKER
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;
}
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
HGLOBAL hTemplate = LoadResource(NULL, hRsrc);
if(!hTemplate)
MessageBox(0,"LoadResource
/*here is where I will output binary exe data ????? somehow ?????*/
return 0;
}
ASKER
OK got it, I will post the results in a few minutes.
ASKER
========================== ======
generated .rc file and added this line
in EXE.rc ------------>
IDI_EXE RCDATA DISCARDABLE "E:\Programming\CPP\Win32\ EmbedResou rceEXE\Mes sage\Relea se\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.
generated .rc file and added this line
in EXE.rc ------------>
IDI_EXE RCDATA DISCARDABLE "E:\Programming\CPP\Win32\
//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
DWORD szRsrc = SizeofResource(NULL, hRsrc);
HGLOBAL hglRsrc = LoadResource(NULL, hRsrc);
if(!hglRsrc )
MessageBox(0,"LoadResource
//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.
ASKER
of course I should return if the handles are NULL....whoops.
Just replace messageBox... with return 0;
Just replace messageBox... with return 0;
1000 RCDATA "..\TheFile.exe"
though you'll have to extract it and save to a temp. file somewhere before you can execute it.