创建子进程输入句柄无效
其实可能造成标准句柄无效的情况我只见过两种,一种是在自身进程中调用SetStdHandle,另外一种是在创建子进程是设置启动信息属性
SetStdHandle
SetStdHandle(STD_INPUT_HANDLE,-1)
SetStdHandle(STD_OUTPUT_HANDLE,-1)
SetStdHandle(STD_ERROR_HANDLE,-1)
STARTUPINFO
#include <iostream>
#include <stdlib.h>
#include <windows.h>
using namespace std;
int main() {//一些必备参数设置
STARTUPINFO si;
memset(&si, 0,
sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.hStdError = -1;
si.hStdOutput = -1;
si.hStdInput = -1;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; //一定要包含这个属性,否则子进程无法继承相应的属性
PROCESS_INFORMATION pi;
if (!CreateProcess(TEXT("c:\\windows\\system32\\notepad.exe"), NULL, NULL,
NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
cout << "CreateFail!" << endl;
exit(1);
} else {
cout << "Success!" << endl;
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return 0;
}
下面进一步了解这个结构体
结构原型
typedef struct _STARTUPINFO {
DWORD cb;
LPTSTR lpReserved;
LPTSTR lpDesktop;
LPTSTR 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;
} STARTUPINFO, *LPSTARTUPINFO;
各个字段的意思在网上应该很好搜,有一个字段比较特殊 dwFlags
dwFlags
标志 含义
STARTF_USESIZE 使用dwXSize 和dwYSize 成员
STARTF_USESHOWWINDOW 使用wShowWindow 成员
STARTF_USEPOSITION 使用dwX 和dwY 成员
STARTF_USECOUNTCHARS 使用dwXCountChars 和dwYCount Chars 成员
STARTF_USEFILLATTRIBUTE 使用dwFillAttribute 成员
STARTF_USESTDHANDLES 使用hStdInput 、hStdOutput 和h StdError 成员
STARTF_RUN_FULLSCREEN 强制在x86 计算机上运行的控制台应用程
这个字段记录了结构体那些属性是有效的,并且以bit OR的形式组合起来
比如你想要设置hStdInput有效,就比必须使用STARTF_USESTDHANDLES
si.hStdInput = hRead;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESTDHANDLES;
在创建进程的时候一定要避免设置标准输入句柄为-1