Easy code to call CreateProcess()

CreateProcess() is simply annoying to call, because of the need to create the input and output structures that CreateProcess() expects. Namely, PROCESS_INFORMATION and STARTUP_INFO. Putting this up as a convenient point to grab code that calls CreateProcess(), and at the same time, short documentation so that the purpose of the dozen parameters are fairly obvious.

Mainly for myself, and anybody who finds it useful to grab.

Short version:

/* Easy Call CreateProcess.
 *
 * Quick and easy way to call Win32 API CreateProcess() without
 * going through all the parameters and creating all the necessary
 * structures.
 *
 * Eugene Ching (@eugeii)
 * 22 May 2014
 */

#include <windows.h>

int create_process(LPCTSTR lpAppName, LPTSTR lpCmdLine) {
  PROCESS_INFORMATION ProcessInfo;
  STARTUPINFO StartupInfo;
  ZeroMemory(&StartupInfo, sizeof(StartupInfo));
  StartupInfo.cb = sizeof(StartupInfo);

  if(CreateProcess(lpAppName, lpCmdLine, 
                   NULL, NULL, FALSE, 0, NULL, NULL, 
                   &StartupInfo, &ProcessInfo)) {
    WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
    CloseHandle(ProcessInfo.hThread);
    CloseHandle(ProcessInfo.hProcess);
  } 
}

int main(void) {
  create_process("c:\\windows\\notepad.exe",                  // App name
                 "c:\\windows\\notepad.exe h:\\myfile.txt");  // Cmd line
}

Documented version:

/* Easy Call CreateProcess.
 *
 * Quick and easy way to call Win32 API CreateProcess() without
 * going through all the parameters and creating all the necessary
 * structures.
 *
 * Eugene Ching (@eugeii)
 * 22 May 2014
 */

#include <windows.h>

int create_process(LPCTSTR lpAppName, LPTSTR lpCmdLine) {
  /* Create PROCESS_INFORMATION structure (output from CreateProcess)

   * typedef struct _PROCESS_INFORMATION {
   *     HANDLE hProcess;          // Handle to tne newly created process
   *     HANDLE hThread;           // Handle to the primary thread
   *     DWORD  dwProcessId;       // The process ID
   *     DWORD  dwThreadId;        // The thread ID
   * } PROCESS_INFORMATION, *LPPROCESS_INFORMATION;
   */
  PROCESS_INFORMATION ProcessInfo;

  /* Create STARTUPINFO structure (input to CreateProcess)
   *   
   * typedef struct _STARTUPINFO {
   *     DWORD  cb;                // Size of structure, in bytes
   *     LPTSTR lpReserved;        // Reserved, must be NULL
   *     LPTSTR lpDesktop;         // Name of the desktop
   *     LPTSTR lpTitle;           // Title of the application
   *     DWORD  dwX;               // location-X
   *     DWORD  dwY;               // location-Y 
   *     DWORD  dwXSize;           // size-width
   *     DWORD  dwYSize;           // size-height
   *     DWORD  dwXCountChars;     // screen buffer width for console processes
   *     DWORD  dwYCountChars;     // screen buffer height for console processes
   *     DWORD  dwFillAttribute;   // initial text and background colors for console processes
   *     DWORD  dwFlags;           // Flags (general)
   *     WORD   wShowWindow;       // Flags for window visibility
   *     WORD   cbReserved2;       // Reserved for C-runtime, must be NULL
   *     LPBYTE lpReserved2;       // Reserved for C-runtime, must be NULL
   *     HANDLE hStdInput;         // standard input
   *     HANDLE hStdOutput;        // standard output
   *     HANDLE hStdError;         // standard error
   * } STARTUPINFO, *LPSTARTUPINFO;
   */
  STARTUPINFO StartupInfo;
  ZeroMemory(&StartupInfo, sizeof(StartupInfo));
  StartupInfo.cb = sizeof(StartupInfo);

  /* Spawn the process
   *
   * BOOL WINAPI CreateProcess(
   *     _In_opt_     LPCTSTR lpApplicationName,
   *     _Inout_opt_  LPTSTR lpCommandLine,
   *     _In_opt_     LPSECURITY_ATTRIBUTES lpProcessAttributes,
   *     _In_opt_     LPSECURITY_ATTRIBUTES lpThreadAttributes,
   *     _In_         BOOL bInheritHandles,
   *     _In_         DWORD dwCreationFlags,
   *     _In_opt_     LPVOID lpEnvironment,
   *     _In_opt_     LPCTSTR lpCurrentDirectory,
   *     _In_         LPSTARTUPINFO lpStartupInfo,
   *     _Out_        LPPROCESS_INFORMATION lpProcessInformation
   * );
   */
  if(CreateProcess(lpAppName,        // lpApplicationName
                   lpCmdLine,        // lpCommandLine
                   NULL,             // lpProcessAttributes
                   NULL,             // lpThreadAttributes
                   FALSE,            // bInheritHandles
                   0,                // dwCreationFlags
                   NULL,             // lpEnvironment
                   NULL,             // lpCurrentDirectory
                   &StartupInfo,     // lpStartupInfo
                   &ProcessInfo)) {  // lpProcessInformation

  // Wait for processes to complete
    WaitForSingleObject(ProcessInfo.hProcess,INFINITE);

  // Clean up
    CloseHandle(ProcessInfo.hThread);
    CloseHandle(ProcessInfo.hProcess);
  }

}

int main(void) {
  create_process("c:\\windows\\notepad.exe",                  // App name
                 "c:\\windows\\notepad.exe h:\\myfile.txt");  // Cmd line
}