Daemonize a process under Microsoft Windows I wrote a simple tool to allow to daemonize any process under Microsoft Windows.

The goal is to push any process into the background with no questions asked. That includes GUI applications, which means that the main window will not be created...or at least not shown. For console applications it will simply detach the process from the current console and not open another one. Usage is simple:

daemonize.exe PROGRAM [ARGUMENTS]


So let's cut to the code:

#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

#include &lt;windows.h&gt;

// The important things to note and know:
//
//  * Only works with ASCII paths and filenames.
//  * Quotes all arguments regardless of content.
//  * SW_HIDE in STARTUPINFO is needed for GUI applications
//  * DETACHED_PROCESS in CreateProcessA is needed for command line applications
//

int main(int argc, char *argv[]) {
    if (argc &lt;= 1) {
        printf("daemonize.exe COMMAND [ARGUMENTS]");
        return 1;
    }

    char* command = argv[1];
    char* arguments = NULL;

    if (argc &gt; 2) {
        // We only need to concatenate arguments if there
        // actually are arguments.
        int idx;

        // Calculate the length of all arguments
        size_t argLength = 0;
        for (idx = 1; idx &lt; argc; idx++) {
            argLength += strlen(argv[idx] + 2 + 1); // One for the space, two for the quotes.
        }
        argLength--; // Strip the last space.

        // Reserve some memory and NULL the new string.
        //The + 1 is the space for the last null character.
        arguments = (char*)malloc(sizeof(char) * (argLength + 1));
        arguments[0] = 0;

        // Now concatenate the arguments.
        for (idx = 1; idx &lt; argc; idx++) {
            strcat(arguments, "\"");
            strcat(arguments, argv[idx]);
            strcat(arguments, "\"");
            if (idx &lt; argc - 1) {
                strcat(arguments, " ");
            }
        }
    }

    STARTUPINFO startInfo;
    PROCESS_INFORMATION process;

    ZeroMemory(&amp;startInfo, sizeof(startInfo));
    ZeroMemory(&amp;process, sizeof(process));

    startInfo.cb = sizeof(startInfo);

    // Tell the system to use/honor the ShowWindow flags.
    startInfo.dwFlags = STARTF_USESHOWWINDOW;
    // Tell the system that the main window of the process should be hidden.
    startInfo.wShowWindow = SW_HIDE;

    if (!CreateProcessA(
            command,            // application name
            arguments,            // command line arguments
            NULL,                // process attributes
            NULL,                // thread attributes
            FALSE,                // inherit (file) handles
            // Detach the process from the current console.
            DETACHED_PROCESS,   // creation flags
            NULL,                // environment
            NULL,                // current directory
            &amp;startInfo,            // startup info
            &amp;process)            // process information
        ) {

        printf("Creation of the process failed, trying to fetch error message...\n");

        long lastError = GetLastError();
        char* message = NULL;

        FormatMessageA(
            FORMAT_MESSAGE_ALLOCATE_BUFFER |
            FORMAT_MESSAGE_ARGUMENT_ARRAY |
            FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_IGNORE_INSERTS, // Flags
            NULL,               // source
            lastError,          // message identifier
            0,                  // language id
            (LPSTR)&amp;message,   // message buffer
            0,                  // size of the message
            NULL                // arguments
        );

        printf(message);

        return 1;
    }

    return 0;
}
It looks good: very good, assuming it works (i.e. has the run-time behaviour that you want: I don't know the effect of calling CreateProcess in that way).

You don't free(arguments) but that doesn't matter because memory will be reclaimed by the O/S when the process exits. Similarly, in theory I'd expect an API call to release message.

I don't see why you need the (LPSTR) cast. Using a cast can hide compiler warnings/errors, which should be fixed instead of their causing errors at run-time.

Instead of int idx; it's better to not define a local variable until the moment at which you initialize it: instead you could say, for (int idx = 1; idx &lt; argc; idx++).

Also, shouldn't it be for (int idx = 2; idx &lt; argc; idx++)? Because, idx=1 is the 'command' parameter, not the first 'argument' parameter.



If when you say "C/C++" you mean "C++", then it's more conventional these days to use std::string instead of C-style strings (but this is an unusually short program; perhaps although I don't know why you want to avoid the hassle of linking to the STL, especially if you know enough to avoid the many pitfalls of C-style string manipulation, which you seem to have).

For example, using std::string you could write the following, which is simpler than the string-manipulation code you have at the moment:

std::string s;
for (int idx = 1; idx &lt; argc; idx++)
{
    s += "\"" + argv[idx] + "\"";
    if (idx &lt; argc - 1) {
        s += " ";
    }
}
char* arguments = strdup(s.c_str());


The reason for strdup in the above is that MSDN says ...


  The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.


... which helps to explain why arguments must be char* not const char*. Sometimes you can ignore these (the windows API sometimes doesn't say its parameters are const when in fact they are), but doing so may be unsafe bad practice (so I use strdup above -- note that strdup'ed memory should be free'ed).