_spawn_wspawn 函式

所有 _spawn 函式都會建立並執行新的處理序:

_spawnl, _wspawnl
_spawnle, _wspawnle
_spawnlp, _wspawnlp
_spawnlpe, _wspawnlpe
_spawnv, _wspawnv
_spawnve, _wspawnve
_spawnvp, _wspawnvp
_spawnvpe, _wspawnvpe

函式名稱結尾的字母決定了變化。

信件 變數
e envp,環境設定的指標陣列,會傳遞至新處理序。
l 命令列引數會分別傳遞至 _spawn 函式。 當某些新進程的參數事先已知時,通常會使用這個尾碼。
p PATH 環境變數,用於尋找要執行的檔案。
v argv,命令列引數的指標陣列,會傳遞至 _spawn 函式。 當新進程的數個參數是變數時,通常會使用這個尾碼。

備註

所有的 _spawn 函式都會建立並執行新的處理序。 它們會根據目前使用中的多位元組字碼頁,自動將多位元組字元字串引數處理為適當且可辨識的多位元組字元序列。 函 _wspawn 式是函式的 _spawn 寬字元版本;它們不會處理多位元組字元字串。 否則,_wspawn 函式的行為會和其 _spawn 對應項目相同。

泛型文字常式對應

Tchar.h 常規 _UNICODE_MBCS 未定義 _MBCS 定義 _UNICODE 定義
_tspawnl _spawnl _spawnl _wspawnl
_tspawnle _spawnle _spawnle _wspawnle
_tspawnlp _spawnlp _spawnlp _wspawnlp
_tspawnlpe _spawnlpe _spawnlpe _wspawnlpe
_tspawnv _spawnv _spawnv _wspawnv
_tspawnve _spawnve _spawnve _wspawnve
_tspawnvp _spawnvp _spawnvp _wspawnvp
_tspawnvpe _spawnvpe _spawnvpe _wspawnvpe

必須有足夠的記憶體才能載入和執行新的處理序。 mode 引數會決定呼叫處理序在 _spawn 之前及期間所採取的動作。 的下列值 mode 定義于 Process.h 中:

Description
_P_OVERLAY 重疊呼叫處理序與新的處理序,會終結呼叫處理序 (與 _exec 呼叫的效果相同)。
_P_WAIT 暫停呼叫執行緒直到新的處理序執行完成 (同步的 _spawn)。
_P_NOWAIT_P_NOWAITO 同時繼續執行呼叫處理序與新的處理序 (非同步的 _spawn)。
_P_DETACH 繼續執行呼叫處理序,新處理序在背景執行,但無法存取主控台或鍵盤。 針對新的處理序呼叫 _cwait 失敗 (非同步的 _spawn)。

cmdname 引數指定當做新處理序執行的檔案,而且可以指定完整路徑 (來自根目錄)、部分路徑 (來自目前的工作目錄) 或僅只檔案名稱。 如果沒有 cmdname 副檔名或結尾沒有句號 (.),函 _spawn 式會先嘗試 .com 副檔名,再嘗試 .exe 副檔名、.bat 副檔名,最後再嘗試 .cmd 副檔名。

cmdname 有副檔名,就只使用該副檔名。 若 cmdname 以句號結尾,_spawn 呼叫會不使用副檔名搜尋 cmdname_spawnlp_spawnlpe_spawnvp_spawnvpe 函式會在 PATH 環境變數指定的目錄中搜尋 cmdname (使用相同的程序)。

如果 cmdname 包含磁片磁碟機規範或任何斜線(也就是,如果是相對路徑), _spawn 則呼叫只會搜尋指定的檔案;不會完成路徑搜尋。

以前,這些函式有些會在成功時將 errno 設成零,目前的行為則是在成功時,如 C 標準所指定的維持 errno 原封不動。 如果您需要模擬舊版的行為,只要在呼叫這些函式前將 errno 設為零即可。

注意

若要確保正確的重疊初始化及終止,請勿使用 setjmplongjmp 函式進入或離開重疊常式。

繁衍進程的引數

若要將引數傳遞給新的處理序,請提供一或多個字元字串的指標當做 _spawn 呼叫中的引數。 這些字元字串會形成繁衍處理序的引數清單。 形成新處理序引數清單的字串合併長度不得超過 1024 個位元組。 每個字串的終止 Null 字元 ('\0') 不會包含在計數中,但會包含空白字元(自動插入至個別引數)。

注意

字串中嵌入的空格可能會導致未預期的行為;例如,傳遞字串 _spawn"hi there" 會導致新處理序取得兩個引數 "hi""there"。 若目的是要使新處理序開啟名為 "hi there" 的檔案,則處理序會失敗。 您可以用引號括住字串來避免此情況:"\"hi there\""

重要

請勿在沒有明確檢查內容的情況下將使用者輸入傳遞至 _spawn_spawn 會導致呼叫 CreateProcess ,因此請記住,不合格的路徑名稱可能會導致潛在的安全性弱點。

您可以將引數指標當做個別的參數 (在 _spawnl_spawnle_spawnlp_spawnlpe 中) 或指標陣列 (在 _spawnv_spawnve_spawnvp_spawnvpe 中) 傳遞。 您必須至少將一個引數或 arg0argv[0] 傳遞至繁衍的進程。 依照慣例,此引數是您會在命令列上輸入的程式名稱。 不同的值不會產生錯誤。

_spawnl_spawnle_spawnlp_spawnlpe 呼叫通常是在預知引數數目時使用。 arg0 引數通常是 cmdname的指標。 arg1argn 的引數是形成新引數清單之字元字串的指標。 argn之後必須有一個 NULL 指標,以標記引數清單的結尾。

_spawnv當新進程的引數數目可變時,、 _spawnve_spawnvp_spawnvpe 呼叫會很有用。 引數的指標會以陣列 argv 的形式傳遞。 引數 argv[0] 通常是真真實模式中路徑的指標,或是受保護模式中的程式名稱指標,而 argv[1] 透過 argv[n] 是形成新引數清單的字元字串指標。 引數必須是 NULL 標記引數 argv[n +1] 清單結尾的指標。

繁衍處理序的環境

執行 _spawn 呼叫之後,已經開啟的檔案仍會在新處理序中保持開啟。 在 _spawnl_spawnlp_spawnv_spawnvp 呼叫中,新處理序會繼承呼叫處理序的環境。 您可以使用 _spawnle_spawnlpe_spawnve_spawnvpe 呼叫透過 envp 引數傳遞環境設定的清單,來改變新處理序的環境。 引數 envp 是字元指標的陣列,其每個項目 (最後一個項目除外) 都會指向定義環境變數的以 Null 終止的字串。 此類字串通常具有此種格式:NAME=value,其中 NAME 是環境變數的名稱,而 value 是設定變數的字串值。 value(未以雙引號括住。陣列的最後一 envp 個專案應該是 NULL 。 當 envp 本身是 NULL 時,繁衍處理序會繼承父代處理序的環境設定。

_spawn 函式可以將開啟的檔案的所有資訊,包括轉譯模式在內,傳遞至新的處理序。 這項資訊會透過環境中的 C_FILE_INFO 項目以真實模式傳遞。 啟始程式碼通常會處理此項目,再從環境中刪除它。 不過,如果 _spawn 函式產生非 C 程序,此項目會保留在環境中。 列印環境會在此項目的定義字串中顯示圖形字元,因為環境資訊以真實模式的二進位格式傳遞。 它不應該對正常作業產生任何其他影響。 在受保護的模式中,環境資訊會以文字格式傳遞,因此不包含任何圖形字元。

您必須先明確清除 (使用 fflush_flushall) 或關閉所有資料流,再呼叫 _spawn 函式。

呼叫 _spawn 常式所建立的新進程不會保留訊號設定。 繁衍處理序會改將訊號設定重設為預設值。

正在重新導向輸出

如果您要從 DLL 或 GUI 應用程式呼叫 _spawn ,而且想要將輸出重新導向至管道,您有兩個選項:

  • 使用 WIN32 API 建立管道,然後呼叫 AllocConsole 、設定啟動結構中的控制碼值,然後呼叫 CreateProcess

  • 呼叫 _popen_wpopen ,這會建立管道,並使用 (或 command.exe /c ) 叫用 cmd.exe /c 應用程式。

範例

// crt_spawn.c
// This program accepts a number in the range
// 1-8 from the command line. Based on the number it receives,
// it executes one of the eight different procedures that
// spawn the process named child. For some of these procedures,
// the CHILD.EXE file must be in the same directory; for
// others, it only has to be in the same path.
//

#include <stdio.h>
#include <process.h>

char *my_env[] =
{
   "THIS=environment will be",
   "PASSED=to child.exe by the",
   "_SPAWNLE=and",
   "_SPAWNLPE=and",
   "_SPAWNVE=and",
   "_SPAWNVPE=functions",
   NULL
};

int main( int argc, char *argv[] )
{
   char *args[4];

   // Set up parameters to be sent:
   args[0] = "child";
   args[1] = "spawn??";
   args[2] = "two";
   args[3] = NULL;

   if (argc <= 2)
   {
      printf( "SYNTAX: SPAWN <1-8> <childprogram>\n" );
      exit( 1 );
   }

   switch (argv[1][0])   // Based on first letter of argument
   {
   case '1':
      _spawnl( _P_WAIT, argv[2], argv[2], "_spawnl", "two", NULL );
      break;
   case '2':
      _spawnle( _P_WAIT, argv[2], argv[2], "_spawnle", "two",
               NULL, my_env );
      break;
   case '3':
      _spawnlp( _P_WAIT, argv[2], argv[2], "_spawnlp", "two", NULL );
      break;
   case '4':
      _spawnlpe( _P_WAIT, argv[2], argv[2], "_spawnlpe", "two",
                NULL, my_env );
      break;
   case '5':
      _spawnv( _P_OVERLAY, argv[2], args );
      break;
   case '6':
      _spawnve( _P_OVERLAY, argv[2], args, my_env );
      break;
   case '7':
      _spawnvp( _P_OVERLAY, argv[2], args );
      break;
   case '8':
      _spawnvpe( _P_OVERLAY, argv[2], args, my_env );
      break;
   default:
      printf( "SYNTAX: SPAWN <1-8> <childprogram>\n" );
      exit( 1 );
   }
   printf( "from SPAWN!\n" );
}
child process output
from SPAWN!

另請參閱

進程和環境控制
abort
atexit
_exec_wexec 函式
exit, _Exit, _exit
_flushall
_getmbcp
_onexit, _onexit_m
_setmbcp
system, _wsystem