[toc]

使用C语言在windows中获得进程句柄

C语言在windows中获得自己的进程句柄

使用GetCurrentProcess()或者-1可以得到自身进程的句柄

1
2
3
4
5
6
7
8
9
10
11
12
13
14

#include <windows.h>
#include <stdio.h>


int main(int argc, char* argv[])
{
DWORD dwProcessId = 116348;
HANDLE hProcess1 = GetCurrentProcess();
printf("hProcess is %p\n", hProcess1);
CloseHandle(hProcess1);
printf("hProcess is %p\n", -1);
return 0;
}

C语言在windows中获得其他进程的句柄

使用OpenProcess函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <windows.h>
#include <stdio.h>


int main(int argc, char* argv[])
{
DWORD dwProcessId = 116348;
HANDLE hProcess1 = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
printf("hProcess is %p\n", hProcess1);
CloseHandle(hProcess1);
HANDLE hProcess2 = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
HANDLE hProcess3 = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
printf("hProcess is %p\n", hProcess2);
printf("hProcess is %p\n", hProcess3);
CloseHandle(hProcess2);
CloseHandle(hProcess3);
return 0;
}

可以看到hProcess1与hProcess2为同一个值,hProcess3的值不同。

windows程序中一个程序获得的句柄能否让其他进程同样拥有?

1. 子进程能否继承父进程句柄?

  • 可以继承父进程中打开的句柄,不能继承父进程的句柄
  1. 父进程代码,打开自身的进程并在创建子进程时将进程传递进去
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <windows.h>
#include <stdio.h>

int main() {
STARTUPINFO si;
PROCESS_INFORMATION pi;
// 打开notepad的句柄
DWORD noteProcessId = GetCurrentProcessId();
HANDLE hNoteProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, noteProcessId);
printf("P:hNoteProcess is %d\n", hNoteProcess);
// 将句柄转换为字符串
char handleStr[20];
sprintf_s(handleStr,20, "%ld", (unsigned long)hNoteProcess);
printf("P:%s\n", handleStr);
// 初始化结构体
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));

// 创建子进程
if (!CreateProcessA(
"D:\\test\\CC++\\c生万物之windows程序开发\\C+windows\\Debug\\Message.exe", // 子进程的路径
handleStr, // 命令行参数,传递父进程句柄
NULL, // 进程句柄不可继承
NULL, // 线程句柄不可继承
TRUE, // 继承句柄
0, // 默认创建标志
NULL, // 使用父进程的环境
NULL, // 使用父进程的当前目录
&si, // 指向STARTUPINFO结构的指针
&pi) // 指向PROCESS_INFORMATION结构的指针
) {
printf("P:CreateProcess failed (%d).\n", GetLastError());
return -1;
}

// 等待子进程结束
WaitForSingleObject(pi.hProcess, INFINITE);
// 关闭句柄
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}

  1. 子进程代码,通过父进程传进来的句柄将对应的进程结束

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include <windows.h>
    #include <stdio.h>

    int main(int argc, char* argv[]) {
    if (argc < 1) {
    printf("No notepad process handle provided.\n");
    return -1;
    }
    printf("c:argv[0]is %s\n",argv[0]);
    // 从命令行参数获取父进程传来的句柄
    HANDLE hNoteProcess = (HANDLE)atoi(argv[0]);
    // 根据传递的句柄结束进程
    if (TerminateProcess(hNoteProcess, 0)) {
    printf("c:notepad process terminated successfully.\n");
    }
    else {
    printf("c:Failed to terminate notepad process (%d).\n", GetLastError());
    }
    return 0;
    }

2. 父进程怎么获得子进程句柄?

代码示例,创建程序后在父进程中利用子进程句柄结束子进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <windows.h>
#include <stdio.h>

int main() {
STARTUPINFO si;
PROCESS_INFORMATION pi;

// 初始化结构体
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));

// 创建子进程
if (!CreateProcessW(
L"c:\\windows\\system32\\calc.exe", // 子进程的路径
NULL, // 命令行参数
NULL, // 进程句柄不可继承
NULL, // 线程句柄不可继承
FALSE, // 不继承句柄
0, // 默认创建标志
NULL, // 使用父进程的环境
NULL, // 使用父进程的当前目录
&si, // 指向STARTUPINFO结构的指针
&pi) // 指向PROCESS_INFORMATION结构的指针
) {
printf("CreateProcess failed (%d).\n", GetLastError());
return -1;
}

printf("Child process created with PID: %d\n", pi.dwProcessId);

// 在这里可以执行其他操作...

// 结束子进程
if (TerminateProcess(pi.hProcess, 0)) {
printf("Child process terminated successfully.\n");
}
else {
printf("Failed to terminate child process (%d).\n", GetLastError());
}

// 关闭句柄
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);

return 0;
}

3.同一个父进程下的子进程句柄能否相互继承?(不能)