如何使用命名管道在 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. 保存该窗体。 若要测试上述代码,第一次启动服务器,并在窗体上的任意位置单击。服务器应用程序现在阻塞且具有挂起,将出现,但它实际上等待客户端连接。然后启动客户端应用程序并单击在"呼叫命名管道"。客户端应发送到服务器将响应以 500 字节的数据值 500。可以设置值 cbBytes 文本框中从 0 到 20000 字节。要停止服务器,只需从客户端发送 0 (零)。客户端可能会收到错误 233 (ERROR_PIPE_NOT_CONNECTED),但这是正常的。

    该示例的另一改进可能包括使用 IO 完成端口和/或非阻塞读取和写入使用重叠 IO。您可以在 Microsoft 平台 SDK 中找到有关这些主题的详细信息。

参考

有几个 InterProcess 通讯 (IPC) 方法在 Windows 2000、 Windows NT 和允许多个进程之间以单向或双向传输数据的 Windows 95 中可用。有关 IPC 方法可用在每个平台上一个完整列表,请参阅 Microsoft 知识库中下面的文章:
95900: 在 Windows NT、 Windows 95 和 Win32s 进程间通信

属性

文章编号: 177696 - 最后修改: 2007年2月12日 - 修订: 2.4
这篇文章中的信息适用于:
  • Microsoft Visual Basic 4.0 专业版
  • Microsoft Visual Basic 5.0 专业版
  • Microsoft Visual Basic 6.0 专业版
  • Microsoft Visual Basic 4.0 企业版
  • Microsoft Visual Basic 5.0 企业版
  • 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
机器翻译
注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。
点击这里察看该文章的英文版: 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