MSDN – Windows Process Programming

Overview

Processes are the fundamental unit of execution in the Windows operating system. This documentation provides guidance on creating, managing, and terminating processes, as well as security considerations and common patterns for inter‑process communication.

Key concepts include:

  • Process creation with CreateProcess and related functions.
  • Process termination using TerminateProcess or graceful exit mechanisms.
  • Security descriptors and token handling.
  • Thread management within a process.

Creating a Process

Use CreateProcess for full control over the child process. For simple launches, ShellExecuteEx is often sufficient.

C++ – Create a Child Process
#include <windows.h>
#include <iostream>

int main()
{
    STARTUPINFO si = { sizeof(si) };
    PROCESS_INFORMATION pi;

    wchar_t cmd[] = L"notepad.exe";

    if (!CreateProcessW(
            nullptr,               // Application name
            cmd,                   // Command line
            nullptr, nullptr,     // Process & thread security
            FALSE,                // Inherit handles?
            0,                    // Creation flags
            nullptr, nullptr,    // Environment, current dir
            &si, &pi))
    {
        std::cerr << "CreateProcess failed: " << GetLastError() << std::endl;
        return 1;
    }

    // Wait until child exits.
    WaitForSingleObject(pi.hProcess, INFINITE);

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    return 0;
}

Terminating a Process

Graceful termination is preferred. When necessary, TerminateProcess forces termination but does not run cleanup handlers.

C++ – Terminate a Process
#include <windows.h>
#include <tlhelp32.h>

bool KillProcessById(DWORD pid)
{
    HANDLE h = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
    if (!h) return false;
    BOOL result = TerminateProcess(h, 0);
    CloseHandle(h);
    return result == TRUE;
}

Process Security

Processes run under a security token that defines privileges. Adjust token privileges with AdjustTokenPrivileges and set security descriptors when creating a process.

C++ – Adjust Token Privileges
#include <windows.h>

BOOL EnablePrivilege(LPCWSTR privilege)
{
    HANDLE hToken;
    if (!OpenProcessToken(GetCurrentProcess(),
        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
        return FALSE;

    LUID luid;
    if (!LookupPrivilegeValueW(nullptr, privilege, &luid)) {
        CloseHandle(hToken);
        return FALSE;
    }

    TOKEN_PRIVILEGES tp = {1, {{luid, SE_PRIVILEGE_ENABLED}}};

    BOOL ok = AdjustTokenPrivileges(hToken, FALSE, &tp, 0, nullptr, nullptr);
    CloseHandle(hToken);
    return ok && GetLastError() == ERROR_SUCCESS;
}

Process and Threads

Every Windows process has at least one primary thread. Use CreateThread or _beginthreadex for additional threads. Synchronize using WaitForSingleObject, events, mutexes, or SRW locks.

To enumerate threads of a process:

C++ – Enumerate Process Threads
#include <windows.h>
#include <tlhelp32.h>
#include <iostream>

void ListThreads(DWORD pid)
{
    HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    if (h == INVALID_HANDLE_VALUE) return;

    THREADENTRY32 te = { sizeof(te) };
    if (Thread32First(h, &te)) {
        do {
            if (te.th32OwnerProcessID == pid)
                std::cout << "Thread ID: " << te.th32ThreadID << std::endl;
        } while (Thread32Next(h, &te));
    }
    CloseHandle(h);
}

Sample: Launch Notepad & Monitor Exit

This example combines creation, waiting, and cleanup. Click the button to run the demo (requires a Windows environment).