2

I'm writing a program, which creates Windows service. So I need two .exe files - one for program, creating service and another for service itself. But I want to combine these two files into one. I have the following idea - open .exe file, which I want to pack (service application) in text editor and then copy its contents to some string. Then I need to create an empty .exe file in required directory and write the string to this file. But I suppose that's not a good idea. What is the best way to solve my problem?

Thanks in advance.

4

2 回答 2

2

For fun I wrote a "launcher" program that uses your method. It works, I tested it with zoomin.exe as the payload.

Once you've created the launcher executable, open both it and the payload file (zoomin.exe in my case) in Notepad++, and copy (using the Edit | Paste Special | Copy Binary Content and Paste Binary Content menu options).

You can find whereabouts in the launcher file the payload goes by searching in Notepad++ for "File Goes Here" and "End".

Note, I do not recommend this in any way, it's fiddly, error-prone and can break easily with different compiler settings. The way I have solved this in the past is, as already commented, to add the payload as a resource, which is much more maintainable.

#include <stdio.h>

#define SIZE_OF_ZOOMIN_EXE 11264
char buffer[SIZE_OF_ZOOMIN_EXE] = "File Goes Here";
char end_of_buffer[] = "End";

int main()
{
    FILE *fp = fopen("myzoomin.exe", "wb");
    fwrite(buffer, sizeof(buffer), 1, fp);
    fclose(fp);
    return 0;
}

Here's an main() function for a self-installing service I wrote in C++ . In addition, the program allows the service to be run interactively.

int main( int argc, char *argv[] ) 
{ 
    SERVICE_TABLE_ENTRY   DispatchTable[] = 
    { 
        { SERVICE_NAME,      Eng3ServiceStart      }, 
        { NULL,              NULL          } 
    }; 

    try {
        if (argc >= 2) {
            if (argc >= 3)
                if (!(logfile = fopen(argv[2], "a")))
                    logfile = stdout;

            if (0 == _stricmp(argv[1], "install")) {
                DeleteEng3Service(); // ignore return value -- don't care if error
                return CreateEng3Service();
            }
            else if (0 == _stricmp(argv[1], "uninstall"))
                return DeleteEng3Service() ;

        } 

        // not installing or uninstalling, start the service,
        // passing it all the command-line arguments.
        if (!StartServiceCtrlDispatcher( DispatchTable ) ) {
            if (GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) {
                fprintf(logfile, "Failed to connect to service. Starting in console mode.\n");
                return svcmain(argc, argv);
            }
            throw sys_ex();
        }

    } catch (exception& ex ) {
        fprintf(logfile, ex.what());
    }
} 
于 2012-10-08T18:47:04.803 回答
1

It should be possible to add binary data as a resouce to a win32 executable.

Using the win32 resource functions this should be feasible.

Googling brought up this: http://www.codeproject.com/Articles/4221/Adding-and-extracting-binary-resources

于 2012-10-11T14:52:39.017 回答