The Windows Processes and Threads 10



Creating Processes (With Code Example)


The CreateProcess() function creates a new process, which runs independently of the creating process. However, for simplicity, the relationship is referred to as a parent-child relationship. The following code example demonstrates how to create a process.

Create a new empty Win32 console application project. Give a suitable project name and change the project location if needed.

Then, add the source file and give it a suitable name.



Next, add the following source code.


#include <windows.h>

#include <stdio.h>

#include <strsafe.h>

#include <wchar.h>


// Prototype

void ErrorHandler(LPTSTR lpszFunction);


// This wmain() is the main or parent process

int wmain(int argc, WCHAR *argv[])




    DWORD Ret = 0, dwPID = 0, dwTID = 0, dwPver = 0;


    ZeroMemory(&si, sizeof(si));

    si.cb = sizeof(si);

    ZeroMemory(&pi, sizeof(pi));


    // Validate the argument

    if(argc != 2)


        wprintf(LUsage: %s [cmdline]\n, argv[0]);

        return 1;



      // Get parent process and...

      dwPID = GetCurrentProcessId();

      wprintf(Lwmain() process ID is %u\n, dwPID);

      // What about the current thread?

      dwTID = GetCurrentThreadId();

      wprintf(Lwmain() thread ID is %u\n, dwTID);

      // More info...

      wprintf(LCommand line: %s\n, GetCommandLine());

      // Other info

      dwPver = GetProcessVersion(dwPID);

      // or dwPver = GetProcessVersion(0);

      wprintf(LProcess version: %u\n, dwPver);


    // Start the child process

    wprintf(LStarting another process i.e. child process...\n);

    if(!CreateProcess(NULL,   // No module name (so use command line - [cmdline])

        argv[1],        // Command line

        NULL,           // Process handle not inheritable

        NULL,           // Thread handle not inheritable

        FALSE,          // Set handle inheritance to FALSE

        0,              // No creation flags

        NULL,           // Use parent's environment block

        NULL,           // Use parent's starting directory

        &si,            // Pointer to STARTUPINFO structure

        &pi )           // Pointer to PROCESS_INFORMATION structure




        return 1;




            wprintf(LCreateProcess() - child process was created successfully!\n);

            wprintf(LProcess ID is %u or %u\n, pi.dwProcessId, GetProcessId(pi.hProcess));

            wprintf(LThread ID is %u\n, pi.dwThreadId);

            // Minimum is Vista, Windows 2003 for the following code

            // wprintf(L Thread ID is %u\n, GetThreadId(pi.hThread));



    // Wait until child process exits.

    wprintf(LWaiting the child process exits...\n);

    // The time-out interval, in milliseconds. If a nonzero value is specified,

    // the function waits until the object is signaled or the interval elapses.

    // If dwMilliseconds is zero, the function does not enter a wait state if

    // the object is not signaled; it always returns immediately. If dwMilliseconds is INFINITE,

    // the function will return only when the object is signaled.

    Ret = WaitForSingleObject( pi.hProcess, INFINITE );

    // WAIT_ABANDONED - 0x00000080L, WAIT_OBJECT_0 - 0x00000000L,


    wprintf(LThe WaitForSingleObject() return value is 0X%.8X\n, Ret);


    // Close process and thread handles

    wprintf(LClosing the process and thread handles...\n);

    if(CloseHandle(pi.hProcess) != 0)

            wprintf(Lpi.hProcess handle was closed successfully!\n);



    if(CloseHandle(pi.hThread) != 0)

            wprintf(Lpi.hThread handle was closed successfully!\n);




      return 0;



// This just redundant, you can use the GetLastError() instead

void ErrorHandler(LPTSTR lpszFunction)


    // Retrieve the system error message for the last-error code

    LPVOID lpMsgBuf;

    LPVOID lpDisplayBuf;

    DWORD dw = GetLastError();









        (LPTSTR) &lpMsgBuf,

        0, NULL );


    // Display the error message

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) lpszFunction) + 40) * sizeof(WCHAR));

    StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(WCHAR), L%s failed with error %u: %s, lpszFunction, dw, lpMsgBuf);

    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, LError, MB_OK);


    // Free error-handling buffer allocations

    if(LocalFree(lpMsgBuf) == NULL)

            wprintf(LlpMsgBuf buffer freed!\n);


            wprintf(LFailed to free lpMsgBuf buffer, error %u\n, GetLastError());


    if(LocalFree(lpDisplayBuf) == NULL)

            wprintf(LlpDisplayBuf buffer freed!\n);


            wprintf(LFailed to free lpDisplayBuf buffer, error %u\n, GetLastError());




Build and run the project. The following screenshot is a sample output when we use the calc (calculator) as the argument. The Windows calculator program should be launched.


Creating processes code example: A sample console program output in action


The following is the Windows calculator.


A sample console program output in action: launching or spawning the calc.exe process


When we see through Windows Task Manager, we can see both processes and their threads respectively.


A sample thread and process in action seen from Windows Task Manager



When we close the calc program, the following screenshot shows the complete output.


Creating processes code example: Spawning new process (thread)


If CreateProcess() succeeds, it returns a PROCESS_INFORMATION structure containing handles and identifiers for the new process and its primary thread. The thread and process handles are created with full access rights, although access can be restricted if you specify security descriptors. When you no longer need these handles, close them by using the CloseHandle() function. You can also create a process using the CreateProcessAsUser() or CreateProcessWithLogonW() function. This allows you to specify the security context of the user account in which the process will execute.



< Processes & Threads 9 | Win32 Process & Thread Programming | Win32 Programming | Processes & Threads 11 >