所有 _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 設為零即可。
注意
若要確保正確的重疊初始化及終止,請勿使用 setjmp 或 longjmp 函式進入或離開重疊常式。
繁衍進程的自變數
若要將引數傳遞給新的處理序,請提供一或多個字元字串的指標當做 _spawn 呼叫中的引數。 這些字元字串會形成繁衍處理序的引數清單。 形成新處理序引數清單的字串合併長度不得超過 1024 個位元組。 每個字串的終止 Null 字元 ('\0') 不會包含在計數中,但會包含空格符(自動插入至個別自變數)。
注意
字串中嵌入的空格可能會導致未預期的行為;例如,傳遞字串 _spawn 至 "hi there" 會導致新處理序取得兩個引數 "hi" 和 "there"。 若目的是要使新處理序開啟名為 "hi there" 的檔案,則處理序會失敗。 您可以用引號括住字串來避免此情況:"\"hi there\""。
重要
請勿在沒有明確檢查內容的情況下將使用者輸入傳遞至 _spawn。 _spawn 會導致呼叫 CreateProcess ,因此請記住,不合格的路徑名稱可能會導致潛在的安全性弱點。
您可以將引數指標當做個別的參數 (在 _spawnl、_spawnle、_spawnlp 和 _spawnlpe 中) 或指標陣列 (在 _spawnv、_spawnve、_spawnvp 和 _spawnvpe 中) 傳遞。 您必須至少將一個自變數或 arg0 argv[0]傳遞至繁衍的進程。 依照慣例,此引數是您會在命令列上輸入的程式名稱。 不同的值不會產生錯誤。
_spawnl、_spawnle、_spawnlp 和 _spawnlpe 呼叫通常是在預知引數數目時使用。 arg0 引數通常是 cmdname的指標。 arg1 到 argn 的引數是形成新引數清單之字元字串的指標。 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