CreateNamedPipeA 函式 (winbase.h)
建立具名管道的實例,並傳回後續管道作業的句柄。 命名管道伺服器進程會使用此函式來建立特定命名管道的第一個實例,並建立其基本屬性,或建立現有命名管道的新實例。
語法
HANDLE CreateNamedPipeA(
[in] LPCSTR lpName,
[in] DWORD dwOpenMode,
[in] DWORD dwPipeMode,
[in] DWORD nMaxInstances,
[in] DWORD nOutBufferSize,
[in] DWORD nInBufferSize,
[in] DWORD nDefaultTimeOut,
[in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes
);
參數
[in] lpName
唯一管道名稱。 這個字串必須具有下列格式:
\\.\pipe\pipename
名稱的管道名稱部分可以包含反斜杠以外的任何字元,包括數位和特殊字元。 整個管道名稱字串長度最多可達 256 個字元。 管道名稱不區分大小寫。
[in] dwOpenMode
開啟模式。
如果 dwOpenMode 指定 0 以外的任何專案或下表所列的旗標,則函式會失敗。
此參數必須指定下列其中一種管道存取模式。 必須針對管道的每個實例指定相同的模式。
模式 | 意義 |
---|---|
|
管道是雙向的;伺服器和客戶端進程都可以讀取和寫入管道。 此模式可讓伺服器對等 GENERIC_READ,並 GENERIC_WRITE 管道的存取權。 當用戶端使用 CreateFile 函式連接到管道時,可以指定 GENERIC_READ 或 GENERIC_WRITE或兩者。 |
|
管道中的數據流程只會從用戶端流向伺服器。 此模式可讓伺服器對管線 GENERIC_READ 存取權。 線上到管道時,客戶端必須指定 GENERIC_WRITE 存取權。 如果客戶端必須 藉由呼叫 getNamedPipeInfo 或 GetNamedPipeHandleState 函式來讀取管道設定,客戶端必須在連接到管道時指定 GENERIC_WRITE 和 FILE_READ_ATTRIBUTES 存取。 |
|
管道中的數據流程只會從伺服器流向用戶端。 此模式可讓伺服器對管線 GENERIC_WRITE 存取權。 用戶端必須在連接到管道時指定 GENERIC_READ 存取權。 如果客戶端必須呼叫 SetNamedPipeHandleState 函式來變更管道設定,客戶端必須在連接到管道時指定 GENERIC_READ 和 FILE_WRITE_ATTRIBUTES 存取權。 |
此參數也可以包含下列一或多個旗標,以啟用寫入和重疊模式。 針對相同管道的不同實例,這些模式可能不同。
模式 | 意義 |
---|---|
|
如果您嘗試使用此旗標建立管道的多個實體,則第一個實例的建立會成功,但下一個實例的建立會失敗並 ERROR_ACCESS_DENIED。 |
|
已啟用寫入模式。 此模式只會影響位元組類型管道上的寫入作業,然後只有在用戶端和伺服器進程位於不同的計算機上時。 如果啟用此模式,寫入命名管道的函式不會傳回,直到寫入的數據透過網路傳輸,且位於遠端電腦上的管道緩衝區中。 如果未啟用此模式,系統會藉由緩衝數據,直到累積最少的位元元組數,或直到經過最大時間為止,來提升網路作業的效率。 |
|
已啟用重疊模式。 如果啟用此模式,執行讀取、寫入和連線作業的函式可能需要大量時間才能立即傳回。 此模式可讓啟動作業的線程在背景執行耗時的作業時執行其他作業。 例如,在重疊模式中,線程可以在管道的多個實例上處理同時的輸入和輸出 (I/O) 作業,或在相同的管道控點上執行同時讀取和寫入作業。 如果未啟用重疊模式,在管道句柄上執行讀取、寫入和連接作業的函式在作業完成之前不會傳回。 ReadFileEx 和 WriteFileEx 函式只能搭配管線控點在重疊模式中使用。 ReadFile、WriteFile、ConnectNamedPipe和 TransactNamedPipe 函式可以同步或重疊的作業來執行。 |
此參數可以包含下列安全性存取模式的任何組合。 針對相同管道的不同實例,這些模式可能不同。
模式 | 意義 |
---|---|
|
呼叫端將具有具名管道的任意訪問控制清單 (ACL) 的寫入許可權。 |
|
呼叫端將具有具名管道擁有者的寫入許可權。 |
|
呼叫端將具有具名管道 SACL 的寫入許可權。 如需詳細資訊,請參閱 Access-Control 清單 (ACL) 和 SACL 存取權。 |
[in] dwPipeMode
管道模式。
如果 dwPipeMode 指定 0 以外的任何專案或下表所列的旗標,函式就會失敗。
您可以指定下列其中一種類型模式。 必須針對管道的每個實例指定相同的類型模式。
模式 | 意義 |
---|---|
|
數據會以位元組數據流的形式寫入管道。 此模式無法與PIPE_READMODE_MESSAGE搭配使用。 管道不會區分在不同寫入作業期間寫入的位元組。 |
|
數據會以訊息數據流的形式寫入管道。 管道會將每個寫入作業期間寫入的位元組視為訊息單位。 GetLastError 函式會在訊息未完全讀取時傳回 ERROR_MORE_DATA。 此模式可以搭配 PIPE_READMODE_MESSAGE 或 PIPE_READMODE_BYTE使用。 |
您可以指定下列其中一個讀取模式。 相同管道的不同實例可以指定不同的讀取模式。
模式 | 意義 |
---|---|
|
數據會以位元組數據流的形式從管道讀取。 此模式可以搭配 PIPE_TYPE_MESSAGE 或 PIPE_TYPE_BYTE使用。 |
|
數據會以訊息數據流的形式從管道讀取。 只有在同時指定 PIPE_TYPE_MESSAGE 時,才能使用此模式。 |
您可以指定下列其中一種等候模式。 相同管道的不同實例可以指定不同的等候模式。
模式 | 意義 |
---|---|
|
已啟用封鎖模式。 在 ReadFile、WriteFile或 ConnectNamedPipe 函式中指定管道句柄時,除非有要讀取的數據、寫入所有數據或用戶端連線,否則作業不會完成。 使用此模式可能表示在某些情況下無限期等候客戶端進程執行動作。 |
|
啟用非封鎖模式。 在此模式中,ReadFile、WriteFile和 ConnectNamedPipe 一律會立即傳回。
請注意,非封鎖模式支援與 Microsoft LAN Manager 2.0 版相容,且不應該用來使用具名管道達到異步 I/O。 如需異步管道 I/O 的詳細資訊,請參閱 同步和重疊的輸入和輸出。 |
您可以指定下列其中一個遠端用戶端模式。 相同管道的不同實例可以指定不同的遠端用戶端模式。
模式 | 意義 |
---|---|
|
您可以從遠端用戶端接受並檢查管道的安全性描述元的連線。 |
|
來自遠端客戶端的聯機會自動遭到拒絕。 |
[in] nMaxInstances
可以為此管道建立的實例數目上限。 管道的第一個實例可以指定此值;管道的其他實例必須指定相同的數位。 可接受的值為範圍 1 到 PIPE_UNLIMITED_INSTANCES (255)。
如果此參數是 PIPE_UNLIMITED_INSTANCES,則可以建立的管道實例數目只會受限於系統資源的可用性。 如果 nMaxInstances 大於 PIPE_UNLIMITED_INSTANCES,則傳回值為 INVALID_HANDLE_VALUE,而 getLastError 會傳回 ERROR_INVALID_PARAMETER。
[in] nOutBufferSize
要保留輸出緩衝區的位元組數目。 如需調整命名管道緩衝區大小的討論,請參閱下列一節。
[in] nInBufferSize
要保留給輸入緩衝區的位元組數目。 如需調整命名管道緩衝區大小的討論,請參閱下列一節。
[in] nDefaultTimeOut
如果 waitNamedPipe 函式指定
值為零會導致預設逾時 50 毫秒。
[in, optional] lpSecurityAttributes
SECURITY_ATTRIBUTES 結構的指標,指定新命名管道的安全性描述元,並判斷子進程是否可以繼承傳回的句柄。 如果 lpSecurityAttributesNULL,則命名管道會取得預設的安全性描述元,而且無法繼承句柄。 具名管道的預設安全性描述元中的 ACL 會將完全控制權授與 LocalSystem 帳戶、系統管理員和建立者擁有者。 它們也會授與 Everyone 群組成員和匿名帳戶的讀取許可權。
傳回值
如果函式成功,傳回值就是具名管道實例伺服器端的句柄。
如果函式失敗,傳回值會 INVALID_HANDLE_VALUE。 若要取得擴充的錯誤資訊,請呼叫 GetLastError。
言論
若要使用 createNamedPipe
具名管道的所有實例都必須指定相同的管道類型(位元組類型或訊息類型)、管道存取(雙工、輸入或輸出)、實例計數和逾時值。 如果使用不同的值,則此函式會失敗,GetLastError 會傳回 ERROR_ACCESS_DENIED。
客戶端進程會使用 CreateFile 或 CallNamedPipe 函式連接到命名管道。 命名管道的用戶端會以位元組模式啟動,即使伺服器端處於訊息模式也一樣。 若要避免接收數據時發生問題,請將用戶端設定為訊息模式。 若要變更管道的模式,管道客戶端必須開啟具有 GENERIC_READ 且 FILE_WRITE_ATTRIBUTES 存取的只讀管道。
在管道客戶端啟動之前,管道伺服器不應該執行封鎖讀取作業。 否則,可能會發生競爭狀況。 這通常發生在初始化程序代碼,例如 C 運行時間時,需要鎖定和檢查繼承的句柄。
每次建立具名管道時,系統會使用非分頁集區建立輸入和輸出緩衝區,這是核心所使用的物理記憶體。 您可以建立的管道實例數目(以及線程和進程等物件)受限於可用的非分頁集區。 每個讀取或寫入要求都需要緩衝區中讀取或寫入數據的空間,再加上內部數據結構的額外空間。
輸入和輸出緩衝區大小為諮詢。 針對命名管道的每個結尾保留的實際緩衝區大小為系統預設值、系統最小值或最大值,或指定的大小四捨五入至下一個配置界限。 指定的緩衝區大小應該夠小,您的進程不會用完非分頁集區,但足以容納一般要求。
每當管道寫入作業發生時,系統會先嘗試對管道寫入配額收取記憶體費用。 如果剩餘的管道寫入配額足以滿足要求,則寫入作業會立即完成。 如果剩餘的管道寫入配額太小而無法滿足要求,系統會嘗試擴充緩衝區,以使用保留給進程的非分頁集區來容納數據。 寫入作業會封鎖,直到從管道讀取數據,以便釋放額外的緩衝區配額。 因此,如果您指定的緩衝區大小太小,系統會視需要增加緩衝區,但缺點是作業會封鎖。 如果作業重疊,系統線程就會遭到封鎖;否則,會封鎖應用程式線程。
若要釋放命名管道所使用的資源,應用程式應該一律在不再需要時關閉句柄,這可藉由呼叫 CloseHandle 函式或與實例句柄相關聯的進程結束來完成。 請注意,具名管道的實例可能有多個相關聯的句柄。 當具名管道實例的最後一個句柄關閉時,一律會刪除具名管道的實例。
Windows 10 版本 1709:管道僅支援在應用程式容器內;例如,從一個UWP進程到另一個屬於相同應用程式的UWP進程。 此外,命名管道必須使用管道名稱的語法 \\.\pipe\LOCAL\
。
例子
如需範例,請參閱 多線程管道伺服器。
要求
要求 | 價值 |
---|---|
最低支援的用戶端 | Windows 2000 專業版 [傳統型應用程式 |UWP 應用程式] |
支援的最低伺服器 | Windows 2000 Server [傳統型應用程式 |UWP 應用程式] |
目標平臺 | 窗戶 |
標頭 | winbase.h (包括 Windows.h) |
連結庫 | Kernel32.lib |
DLL | Kernel32.dll |