Você está offline; aguardando reconexão

Como usar Named Pipes em um programa de 32 bits Visual Basic

IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.

Clique aqui para ver a versão em Inglês deste artigo: 177696
Sumário
Visual Basic pode criar aplicativos que se comunicar com outros processos por meio de pipes nomeados. O pipe nomeado deve ser criado no Windows 2000 ou Windows NT; no entanto, você pode ler e gravar desse pipe de qualquer plataforma de 32 bits.

Este artigo demonstra comunicação cliente/servidor usando um pipe nomeado no Visual Basic.
Mais Informações
Neste artigo, o processo de criar o NamedPipe é chamado de servidor e o processo de conexão com o pipe nomeado é chamado de cliente.

Existem seis etapas para criar um servidor de pipe nomeado:
  1. Crie um token de segurança para o pipe permitir o acesso a (para fazer um pipe nomeado disponíveis a qualquer processo criando um token de segurança com uma condicional acesso controle DACL (lista) que tem zero entradas nela).
  2. Crie o pipe nomeado.
  3. Chame ConnectNamedPipe para bloquear até que um cliente se conecta.
  4. Chame ReadFile e/ou WriteFile para se comunicar através do pipe.
  5. Chamar DisconnectNamedPipe quando o processo for concluído usando o pipe.
  6. Qualquer CloseHandle no pipe nomeado ou vá para a etapa 4.
Há três etapas para usar um pipe nomeado do cliente pipe nomeado:
  1. Chame CreateFile para obter um identificador para o pipe nomeado.
  2. Chame ReadFile e/ou WriteFile para se comunicar através do pipe.
  3. Ligar CloseHandle filehandle criado no CreateFile.
Como alternativa, você poderia chamar CallNamedPipe, que executa uma única transação sobre o pipe. CallNamedPipe abre o pipe, grava a ele, lê a partir dele e fecha o pipe. Isso é o que faz o cliente abaixo.

O exemplo a seguir demonstra como criar um servidor de pipe nomeado e cliente. Ele implementa somente as funções mais rudimentares necessárias para fazer isso, com um mínimo de verificação de erro. Um programa totalmente funcional deve verificar os valores de retorno do API que é chamado, em vez de supondo que estavam bem-sucedidas.

Servidor de pipe nomeado

  1. Crie um novo projeto. O Form1 é criado por padrão.
  2. Adicione o seguinte código para o formulário:
       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. Criar um novo módulo e adicionar as seguintes declarações:
       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. Salve o formulário.

Cliente de pipe nomeado

  1. Crie um novo projeto. O Form1 é criado por padrão.
  2. Adicione os seguintes controles ao formulário:
       Type             Name               Caption/Default Value   ----             ----               ---------------------   TextBox          cbBytes            500   CommandButton    cmdCallNamedPipe   Call Named Pipe   TextBox          txtReceive					
  3. Adicione o seguinte código para o formulário:
       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. Observe que, se o servidor estiver sendo executado em um computador diferente do qual o cliente é, você precisa alterar o '. ' no szPipeName variável com o nome da máquina do servidor.
  5. Salve o formulário. Para testar o código acima, primeiro iniciar o servidor e clique em qualquer lugar no formulário. O aplicativo do servidor é agora o bloqueio e será exibida para ter travado, mas, na verdade, está aguardando o cliente se conecte. Em seguida, iniciar o aplicativo cliente e clique no "pipe de nome chamada". O cliente deve enviar o valor 500 para o servidor, que responderá com 500 bytes de dados. Você pode definir o valor na caixa de texto cbBytes de 0 para bytes 20000. Para parar o servidor, simplesmente envie 0 (zero) do cliente. O cliente pode receber o erro 233 (ERROR_PIPE_NOT_CONNECTED), mas isso é normal.

    Outro aprimoramento para o exemplo pode incluir o uso de portas de conclusão de E/S e/ou bloqueio não leituras e gravações usando E/S sobrepostas. Você pode encontrar mais informações sobre esses assuntos no SDK da plataforma Microsoft.
Referências
Há vários métodos InterProcess Communication (IPC) disponíveis no Windows 2000, Windows NT e Windows 95 que permitem a transferência unidirecional ou bidirecional de dados entre vários processos. Para obter uma lista completa dos métodos de IPC disponíveis em cada plataforma, consulte o seguinte artigo na Base de dados de Conhecimento da Microsoft:
95900: Interprocess Communication no Windows NT, Windows 95 e Win32s

Aviso: este artigo foi traduzido automaticamente

Propriedades

ID do Artigo: 177696 - Última Revisão: 02/12/2007 19:08:32 - Revisão: 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, Interface de Programação de Aplicativos do Microsoft Win32, the operating system: Microsoft Windows 2000, Microsoft Windows 95, Microsoft Windows Millennium Edition

  • kbmt kbapi kbhowto KB177696 KbMtpt
Comentários
(m);