Solved

include an EXE at compile time

Posted on 2004-10-27
512 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
Question by:cafechris
    11 Comments
     
    LVL 12

    Expert Comment

    by:andrewjb
    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
    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
    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
     
    LVL 12

    Expert Comment

    by:andrewjb
    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
    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:
    ??

    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
    Ok I will try it. I hope I can get to it today, if not , then tomorrow.
    0
     
    LVL 1

    Author Comment

    by:cafechris
    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
    OK got it, I will post the results in a few minutes.
    0
     
    LVL 1

    Author Comment

    by:cafechris
    ================================
    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
    of course I should return if the handles are NULL....whoops.
    Just replace messageBox... with return 0;
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Free Trending Threat Insights Every Day

    Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

    Most of the sites are being standardized with W3C Web Standards. W3C provides lot of web standard services to the web. They have the web specification, process and documentation for all the web standards. You can apply HTML, CSS and Accessibility st…
    Shoutout to Emily Plummer (http://www.experts-exchange.com/members/eplummer26.html) for giving me this article! She did most of it, I just finished it up and posted it for her :)    Introduction In a previous article (http://www.experts-exchang…
    The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
    The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

    857 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

    Need Help in Real-Time?

    Connect with top rated Experts

    16 Experts available now in Live!

    Get 1:1 Help Now