_spawn,_wspawn 函式
每個_spawn函式會建立並執行新的處理程序:
結尾的函式名稱的字母決定變化。
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 中所定義:
_P_OVERLAY
覆疊 a 呼叫處理與新的過程中,損毀呼叫處理序 (相同效果為_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函式搜尋cmdname (使用相同的程序) 中所指定的目錄PATH環境變數。
如果cmdname (亦即,如果它是相對路徑) 包含磁碟機代碼或任何斜線、 _spawn呼叫僅會搜尋指定的檔案類型。 沒有路徑搜尋完成。
在過去,其中幾個函式組errno設為零都成功。 目前的行為是將errno原封不動地成功,如同 c 標準所指定。 如果您需要模擬舊的行為,設定errno設為零之前呼叫這些函式。
注意事項 |
---|
如果要確保正確的覆疊初始化和終止,請勿使用setjmp或longjmp進入或離開覆疊常式的函式。 |
繁衍 (spawn) 的程序的引數
若要將引數傳遞至新的處理序中,提供一或多個指標為字元字串做為引數,在_spawn呼叫。 這些字元的字串會形成繁衍 (spawn) 的程序的引數清單。 形成新的處理序的引數清單的字串的長度不可超過 1024 個位元組。 結束的 null 字元 ('\ 0') 每個字串不包含在計數中,但包含 (自動插入來分隔引數) 的空格字元。
注意事項 |
---|
在字串中內嵌的空格,可能會造成未預期的行為。 比方說,傳遞_spawn字串"hi there"取得兩個引數,新的處理序,將會導致"hi"和"there"。如果目的是讓新的處理程序開啟檔案,名為 「 大家好那里",程序都會失敗。您可以避免這種所括住的字串: "\"hi there\""。 |
安全性提示 |
---|
不要傳送使用者的輸入_spawn而不會明確地檢查其內容。_spawn將會導致呼叫 CreateProcess ,請記住該不合格的路徑名稱可能會導致潛在的安全性弱點。 |
您可以為不同的引數將傳遞引數的指標 (在_spawnl, _spawnle, _spawnlp,以及_spawnlpe) 或做為陣列的指標 (在_spawnv, _spawnve, _spawnvp,和_spawnvpe)。 您必須傳遞一個以上的引數, arg0或argv[0],以繁衍 (spawn) 的程序。 依照慣例,此引數會是程式的您可以將它鍵入命令列上名稱。 不同的值不會產生錯誤。
_spawnl, _spawnle, _spawnlp,以及_spawnlpe的呼叫通常用在事先知道引數數目時的情況下。 arg0引數通常是變數的指標, cmdname。 引數arg1到argn會形成新的引數清單的字元字串的指標。 遵循argn,一定要有NULL標記的引數清單結尾的指標。
_spawnv, _spawnve, _spawnvp,以及_spawnvpe變動的引數至新的處理序時,呼叫都很有用。 引數的指標會傳遞做為陣列中, argv*.* 引數argv[0] 通常是路徑是指向在真實模式或程式名稱在受保護模式中,以及argv[1] 透過argvn 會建立新的引數清單的程序的字元字串的指標。 引數argvn + 1] 必須是NULL標記的引數清單結尾的指標。
繁衍 (spawn) 的程序的環境
檔案開啟時_spawn呼叫後仍保持開啟新的處理序中。 在_spawnl, _spawnlp, _spawnv,以及_spawnvp呼叫,新的處理序會繼承呼叫程序的環境。 您可以使用_spawnle, _spawnlpe, _spawnve,以及_spawnvpe呼叫針對新的處理序的環境改變藉由傳遞一份環境設定,透過envp引數。 引數envp是字元指標陣列,每個元素 (除了最後一個項目) 都指向 null 結束的字串,定義環境變數。 這樣的字串通常會有表單NAME=value , NAME是環境變數的名稱和value已設定該變數的字串值。 (請注意, value沒有括在雙引號。) 最後一個項目envp陣列應該NULL。 當envp本身是NULL,繁衍 (spawn) 的程序會繼承父處理序的環境設定。
_spawn函式可以傳遞開啟的檔案,包括轉譯模式中,以新的處理序相關的所有資訊。 這項資訊就會傳入真實模式透過C_FILE_INFO環境中的項目。 啟始程式碼通常會處理此項目,然後將其從環境中刪除。 不過,如果_spawn函式會產生非 c 程序,此項目會留在環境中。 因為環境資訊以二進位格式超過在真實模式中定義的字串中此項目列印環境顯示圖形的字元。 它不應有任何其他對正常作業的效果。 在受保護模式中,環境資訊會以文字形式傳遞,因此未包含圖形字元。
您必須明確地排清 (使用fflush或_flushall) 或關閉任何電話之前的資料流_spawn函式。
新的處理程序呼叫所建立的_spawn常式不會保留訊號設定。 相反地,繁衍 (spawn) 的程序會將訊號設定重設預設值。
將輸出重新導向
如果您呼叫_spawn從 DLL 或 GUI 應用程式,並想要將輸出重新導向至管道、 您有兩種選擇:
使用 Win32 API 來建立管道,然後呼叫 AllocConsole,將控制代碼值設定在啟動結構和呼叫 CreateProcess。
呼叫_popen _wpopen它會建立管道,並叫用應用程式使用cmd.exe /c (或command.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" );
}