如何在 Visual Basic 32 位元程式中使用具名的管道

文章翻譯 文章翻譯
文章編號: 177696 - 檢視此文章適用的產品。
全部展開 | 全部摺疊

在此頁中

結論

Visual Basic 可以建立透過具名管道 」 的方式傳達給其他處理程序的應用程式。具名管道必須建立在 Windows 2000 或 Windows NT 上 ; 但是,您可以從讀取和寫入至該管道任何 32 位元平台。

本文將告訴您,在 Visual Basic 中使用具名管道的用戶端/伺服器通訊。

其他相關資訊

此文件中建立 [NamedPipe 過程稱為 「 伺服器,並連線到具名管道程序稱為用戶端。

有六個步驟來建立具名的管道伺服器:
  1. 建立管道允許存取它以使具名管道藉由建立安全性權杖與一個判別存取控制清單 (DACL) 有零個項目中可用於任何程序) 的安全性語彙基元。
  2. 建立命名的管道。
  3. 呼叫 ConnectNamedPipe 封鎖,直到用戶端連線為止。
  4. 呼叫 ReadFile 和/或 WriteFile 以透過管道進行通訊。
  5. 在程序完成時呼叫 DisconnectNamedPipe 使用管道。
  6. 具名的管道或移回至步驟 4 上任一 CloseHandle。
有三個步驟使用 「 具名管道用戶端的具名管道:
  1. 呼叫 CreateFile 取得具名管道的控制代碼。
  2. 呼叫 ReadFile 和/或 WriteFile 以透過管道進行通訊。
  3. 呼叫 CreateFile 中建立 filehandle CloseHandle。
或者,您可以把透過管道執行單次交易的 CallNamedPipe。CallNamedPipe 開啟管道,將它寫入,會從它,讀取,然後關閉管道。這是下列用戶端會有什麼效果。

下列範例會示範如何建立具名管道伺服器和用戶端。它會實作僅最基本功能所需執行這項操作,以最少數量的錯誤檢查。完整功能的程式應該檢查 API 的所呼叫的傳回值,而不是假設他們都已成功。

具名的管道伺服器

  1. 建立新的專案。預設會建立 Form1。
  2. 將下列程式碼加入至表單:
       Option Explicit
       Private Const szPipeName = "\\.\pipe\bigtest"
       Private Const BUFFSIZE = 20000
       Private BigBuffer(BUFFSIZE) As Byte, pSD As Long
       Private sa As SECURITY_ATTRIBUTES
       Private hPipe As Long
    
       Private Sub Form_Click()
          Dim i As Long, dwOpenMode As Long, dwPipeMode As Long
          Dim res As Long, nCount As Long, cbnCount As Long
          For i = 0 To BUFFSIZE - 1       'Fill an array of numbers
             BigBuffer(i) = i Mod 256
          Next i
    
          'Create the NULL security token for the pipe
          pSD = GlobalAlloc(GPTR, SECURITY_DESCRIPTOR_MIN_LENGTH)
          res = InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)
          res = SetSecurityDescriptorDacl(pSD, -1, 0, 0)
          sa.nLength = LenB(sa)
          sa.lpSecurityDescriptor = pSD
          sa.bInheritHandle = True
    
          'Create the Named Pipe
          dwOpenMode = PIPE_ACCESS_DUPLEX Or FILE_FLAG_WRITE_THROUGH
          dwPipeMode = PIPE_WAIT Or PIPE_TYPE_MESSAGE Or PIPE_READMODE_MESSAGE
          hPipe = CreateNamedPipe(szPipeName, dwOpenMode, dwPipeMode, _
                                  10, 10000, 2000, 10000, sa)
    
          Do  'Wait for a connection, block until a client connects
             res = ConnectNamedPipe(hPipe, ByVal 0)
    
             'Read/Write data over the pipe
             cbnCount = 4
    
             res = ReadFile(hPipe, nCount, LenB(nCount), cbnCount, ByVal 0)
    
             If nCount <> 0 Then
    
                If nCount > BUFFSIZE Then 'Client requested nCount bytes
                   nCount = BUFFSIZE      'but only send up to 20000 bytes
                End If
                'Write the number of bytes requested
                res = WriteFile(hPipe, BigBuffer(0), nCount, cbnCount, ByVal 0)
                'Make sure the write is finished
                res = FlushFileBuffers(hPipe)
             End If
    
             'Disconnect the NamedPipe
             res = DisconnectNamedPipe(hPipe)
          Loop Until nCount = 0
    
          'Close the pipe handle
          CloseHandle hPipe
          GlobalFree (pSD)
          End
       End Sub
    					
  3. 新的模組,然後新增下列宣告:
       Option Explicit
    
       Public Const FILE_ATTRIBUTE_NORMAL = &H80
       Public Const FILE_FLAG_NO_BUFFERING = &H20000000
       Public Const FILE_FLAG_WRITE_THROUGH = &H80000000
    
       Public Const PIPE_ACCESS_DUPLEX = &H3
       Public Const PIPE_READMODE_MESSAGE = &H2
       Public Const PIPE_TYPE_MESSAGE = &H4
       Public Const PIPE_WAIT = &H0
    
       Public Const INVALID_HANDLE_VALUE = -1
    
       Public Const SECURITY_DESCRIPTOR_MIN_LENGTH = (20)
       Public Const SECURITY_DESCRIPTOR_REVISION = (1)
    
       Type SECURITY_ATTRIBUTES
               nLength As Long
               lpSecurityDescriptor As Long
               bInheritHandle As Long
       End Type
    
       Public Const GMEM_FIXED = &H0
       Public Const GMEM_ZEROINIT = &H40
       Public Const GPTR = (GMEM_FIXED Or GMEM_ZEROINIT)
    
       Declare Function GlobalAlloc Lib "kernel32" ( _
          ByVal wFlags As Long, ByVal dwBytes As Long) As Long
       Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
       Declare Function CreateNamedPipe Lib "kernel32" Alias _
          "CreateNamedPipeA" ( _
          ByVal lpName As String, _
          ByVal dwOpenMode As Long, _
          ByVal dwPipeMode As Long, _
          ByVal nMaxInstances As Long, _
          ByVal nOutBufferSize As Long, _
          ByVal nInBufferSize As Long, _
          ByVal nDefaultTimeOut As Long, _
          lpSecurityAttributes As Any) As Long
    
       Declare Function InitializeSecurityDescriptor Lib "advapi32.dll" ( _
          ByVal pSecurityDescriptor As Long, _
          ByVal dwRevision As Long) As Long
    
       Declare Function SetSecurityDescriptorDacl Lib "advapi32.dll" ( _
          ByVal pSecurityDescriptor As Long, _
          ByVal bDaclPresent As Long, _
          ByVal pDacl As Long, _
          ByVal bDaclDefaulted As Long) As Long
    
       Declare Function ConnectNamedPipe Lib "kernel32" ( _
          ByVal hNamedPipe As Long, _
          lpOverlapped As Any) As Long
    
       Declare Function DisconnectNamedPipe Lib "kernel32" ( _
          ByVal hNamedPipe As Long) As Long
    
       Declare Function WriteFile Lib "kernel32" ( _
          ByVal hFile As Long, _
          lpBuffer As Any, _
          ByVal nNumberOfBytesToWrite As Long, _
          lpNumberOfBytesWritten As Long, _
          lpOverlapped As Any) As Long
    
       Declare Function ReadFile Lib "kernel32" ( _
          ByVal hFile As Long, _
          lpBuffer As Any, _
          ByVal nNumberOfBytesToRead As Long, _
          lpNumberOfBytesRead As Long, _
          lpOverlapped As Any) As Long
    
       Declare Function FlushFileBuffers Lib "kernel32" ( _
          ByVal hFile As Long) As Long
    
       Declare Function CloseHandle Lib "kernel32" ( _
          ByVal hObject As Long) As Long
    					
  4. 儲存表單。

具名的管道用戶端

  1. 建立新的專案。預設會建立 Form1。
  2. 將下列控制項加入至表單:
       Type             Name               Caption/Default Value
       ----             ----               ---------------------
       TextBox          cbBytes            500
       CommandButton    cmdCallNamedPipe   Call Named Pipe
       TextBox          txtReceive
    					
  3. 將下列程式碼加入至表單:
       Option Explicit
       Private Const szPipeName = "\\.\pipe\bigtest", BUFFSIZE = 20000
       Private Declare Function CallNamedPipe Lib "kernel32" Alias _
          "CallNamedPipeA" ( _
          ByVal lpNamedPipeName As String, _
          lpInBuffer As Any, _
          ByVal nInBufferSize As Long, _
          lpOutBuffer As Any, _
          ByVal nOutBufferSize As Long, _
          lpBytesRead As Long, _
          ByVal nTimeOut As Long) As Long
    
       Private Sub cmdCallNamedPipe_Click()
          Dim res As Long, myStr As String, i As Long, cbRead As Long
          Dim numBytes As Long, bArray() As Byte, temp As String
    
          numBytes = cbBytes.Text
          If cbBytes.Text < 0 Then
             MsgBox "Value must be at least 0.", vbOKOnly
             Exit Sub
          End If
          If numBytes > BUFFSIZE Then
             numBytes = BUFFSIZE
          End If
          ReDim bArray(numBytes)  'Build the return buffer
    
          'Call CallNamedPipe to do the transaction all at once
          res = CallNamedPipe(szPipeName, numBytes, LenB(numBytes), _
             bArray(0), numBytes, _
             cbRead, 30000) 'Wait up to 30 seconds for a response
    
          If res > 0 Then
             temp = Format(bArray(0), " 000")
             For i = 1 To cbRead - 1
                If (i Mod 16) = 0 Then temp = temp & vbCrLf
                temp = temp & " " & Format(bArray(i), "000")
             Next i
             txtReceive.Text = temp
          Else
             MsgBox "Error number " & Err.LastDllError & _
                    " attempting to call CallNamedPipe.", vbOKOnly
          End If
       End Sub
    
    					
  4. 請注意是否伺服器正在執行而不是用戶端是機器上,必須變更 ' ' 中變數 szPipeName 伺服器機器的名稱。
  5. 儲存表單。 若要測試上述程式碼,先啟動伺服器,並按一下表單上的任何位置。伺服器應用程式現在封鎖,並會顯示有無反應,但它實際上等待用戶端連線。然後啟動用戶端應用程式,並按一下"Call 具名管道 」。用戶端應該傳送到伺服器會回應以 500 位元組的資料值 500。您可以從 0 設定值 cbBytes 文字方塊中,為 20000 位元組。若要停止伺服器,只是從用戶端傳送 0 (零)。用戶端可能會收到錯誤 233 (ERROR_PIPE_NOT_CONNECTED),但這是正常。

    範例的另一個改進可能包括 IO 完成連接埠及 (或) 未封鎖讀取的使用,以及寫入使用重疊的 IO。您可以在 Microsoft 平台 SDK 中找到需這些主題的詳細資訊。

?考

沒有可用在 Windows 2000、 Windows NT 和 Windows 95 允許單向或雙向的資料傳送多個處理序之間的數個 InterProcess 通訊 (IPC) 方法。如 IPC 方法各平台上可用的完整清單,請參閱 「 Microsoft 知識庫 」 中下列文:
95900: interprocess Windows NT、 Windows 95 和 Win32s 上的通訊

屬性

文章編號: 177696 - 上次校閱: 2007年2月12日 - 版次: 2.4
這篇文章中的資訊適用於:
  • Microsoft Visual Basic 4.0 Professional Edition
  • Microsoft Visual Basic 5.0 Professional Edition
  • Microsoft Visual Basic 6.0 Professional Edition
  • Microsoft Visual Basic 4.0 Enterprise Edition
  • Microsoft Visual Basic 5.0 Enterprise Edition
  • Microsoft Visual Basic Enterprise Edition for Windows 6.0
  • Microsoft Windows NT 4.0
  • Microsoft Windows NT 3.51 Service Pack 5
  • Microsoft Windows NT 4.0
  • Microsoft Windows 98 Standard Edition
  • Microsoft Win32 Application Programming Interface
  • the operating system: Microsoft Windows 2000
  • Microsoft Windows 95
  • Microsoft Windows Millennium Edition
關鍵字:?
kbmt kbapi kbhowto KB177696 KbMtzh
機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:177696
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。

提供意見

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com