プロセスの作成
CreateProcess
関数を用いて新しいプロセスとプライマリスレッドを作成します。
なお、作成されるプロセスのウインドウに関する指定する情報はSTARTUPINFO
構造体に設定します。
また、新しいプロセスは呼び出し元プロセスのセキュリティ コンテキストで実行されます。
Windowsはプロセスを作成するとスレッドが必ず1つ作成されます。
このスレッドはプライマリスレッド
と呼ばれます。
関数が成功すると、戻り値は0以外になります。関数が失敗した場合は、0を返します。
また、起動したプロセスに関する情報はPROCESS_INFORMATION
構造体に格納されます。
BOOL CreateProcessA(
[in, optional] LPCSTR lpApplicationName,
[in, out, optional] LPSTR lpCommandLine,
[in, optional] LPSECURITY_ATTRIBUTES lpProcessAttributes,
[in, optional] LPSECURITY_ATTRIBUTES lpThreadAttributes,
[in] BOOL bInheritHandles,
[in] DWORD dwCreationFlags,
[in, optional] LPVOID lpEnvironment,
[in, optional] LPCSTR lpCurrentDirectory,
[in] LPSTARTUPINFOA lpStartupInfo,
[out] LPPROCESS_INFORMATION lpProcessInformation
);
typedef struct _STARTUPINFOA {
DWORD cb;
LPSTR lpReserved;
LPSTR lpDesktop;
LPSTR lpTitle;
DWORD dwX;
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags;
WORD wShowWindow;
WORD cbReserved2;
LPBYTE lpReserved2;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
} STARTUPINFOA, *LPSTARTUPINFOA;
typedef struct _PROCESS_INFORMATION {
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
} PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;
なおプロセス作成後、プロセスへアクセス不要になった時点でハンドルをクローズする必要があります。
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
サンプルプログラム
#include <windows.h>
#include <stdio.h>
int WINAPI main() {
STARTUPINFO si;
PROCESS_INFORMATION pi;
// 構造体の確保したメモリ領域を0で埋める(=初期化)
ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
// STARTUPINFO構造体のサイズを設定する
si.cb = sizeof(si);
// 起動したいプロセス名
char pName[] = "notepad.exe";
/* PROCESS_INFORMATION
CreateProcessで作成されたプロセスとそのプライマリスレッドに関する情報が保存される
HANDLE hProcess 作成されたプロセスのハンドル
HANDLE hThread 作成されたプライマリスレッドのハンドル
DWORD dwProcessId 作成されたプロセスのID
DWORD dwThreadId 作成されたプライマリスレッドのID
*/
/* CreateProcess
CreateProcessの第1引数と第2引数で指定する差分
第1引数:フルパスで実行したいファイルを指定しなければならない
第2引数:キーワード(notepad, calc.exe)で実行することが可能
*/
if (CreateProcess(NULL, pName, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) == 0) {
printf("Failed to create process\n");
return 1;
}
// 情報の表示
printf("Process ID\t%d\n", pi.dwProcessId);
printf("Thread ID\t%d\n", pi.dwThreadId);
if (CloseHandle(pi.hProcess) == 0 || CloseHandle(pi.hThread) == 0) {
printf("Failed to close handle\n");
return 1;
}
return 0;
}
プロセスを開く
OpenProcess
関数を用いて既に起動しているローカルのプロセスオブジェクトを開きます。
関数が成功した場合、戻り値は指定されたプロセスに対する開いているハンドルです。関数が失敗した場合は、返される値はNULLです。
HANDLE OpenProcess(
[in] DWORD dwDesiredAccess,
[in] BOOL bInheritHandle,
[in] DWORD dwProcessId
);
プロセスの強制終了
TerminalteProcess
関数を用いて、指定したプロセスとそのすべてのスレッドを強制終了
します。なお、ハンドルはPROCESS_TERMINATE
のアクセス権限を有している必要があります。
関数が成功すると、戻り値は0以外になります。関数が失敗した場合は、0を返します。
BOOL TerminateProcess(
[in] HANDLE hProcess,
[in] UINT uExitCode
);
サンプルプログラム
プログラムの流れとしては以下のとおりである。なお、プログラム起動時には第1引数として終了させたいプロセスのPIDを指定する。
# 1756はユーザー権限で動作しているnotepad.exe
>example_TerminateProcess.exe 1756
Exit Code:259
Success to terminate process
- 終了させるプロセスのハンドルを取得する
- GetExitCodeProcess関数を使用して終了コードを取得する
- TerminateProcess関数で終了する
#include <windows.h>
#include <stdio.h>
int WINAPI main(int argc, char* argv[]) {
DWORD pid = atoi(argv[1]);
// 1.対象プロセスのハンドルを取得
// GetExitCodeProcess関数を実行するためには、アクセス権限「PROCESS_QUERY_LIMITED_INFORMATION」を有していなければならない
// TerminateProcess関数を実行するためには、アクセス権限「PROCESS_TERMINATE」を有していなければならない
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
if (hProcess == NULL) {
printf("OpenProcess failed\n");
return 1;
}
// 2.終了コードの取得
DWORD ExitCode = 0;
if (GetExitCodeProcess(hProcess, &ExitCode) == 0) {
printf("GetExitCodeProcess failed\n");
CloseHandle(hProcess);
return 1;
}
printf("Exit Code:%d\n", ExitCode);
// 3.プロセスの強制終了
if (TerminateProcess(hProcess, ExitCode) == 0) {
printf("TerminateProcess failed\n");
CloseHandle(hProcess);
return 1;
}
else {
WaitForSingleObject(hProcess, INFINITE);
printf("Success to terminate process\n");
}
CloseHandle(hProcess);
return 0;
}