1. 程式人生 > 其它 >建立子程序輸入控制代碼無效

建立子程序輸入控制代碼無效

其實可能造成標準控制代碼無效的情況我只見過兩種,一種是在自身程序中呼叫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