プロセス間の通信(パイプ)          <TOP>


CreatePipe 匿名パイプの作成
ReadFile ファイルからデータを読み取る
CreateProcess プロセスの起動
CloseHandle オープンされているオブジェクトハンドルをクローズ
PeekNamedPipe パイプの内容を調べる
WaitForSingleObject 指定された時間が経過するまでスレッドをスリープ


例では、ipconfig.exeのデータを取得しています。
左:WindowsXP    右:Windows2000

 

コマンドプロンプトで確認したところ

 

'================================================================
'= プロセス間の通信(パイプ)
'=    (CreatePipu.bas)
'================================================================
#include "Windows.bi"

Type SECURITY_ATTRIBUTES
    nLength              As Long
    lpSecurityDescriptor As Long
    bInheritHandle       As Long
End Type
      
Type STARTUPINFO
    cb              As Long
    lpReserved      As Long
    lpDesktop       As Long
    lpTitle         As Long
    dwX             As Long
    dwY             As Long
    dwXSize         As Long
    dwYSize         As Long
    dwXCountChars   As Long
    dwYCountChars   As Long
    dwFillAttribute As Long
    dwFlags         As Long
    wShowWindow     As Integer
    cbReserved2     As Integer
    lpReserved2     As Long
    hStdInput       As Long
    hStdOutput      As Long
    hStdError       As Long
End Type
      
Type PROCESS_INFORMATION
    hProcess    As Long
    hThread     As Long
    dwProcessID As Long
    dwThreadID  As Long
End Type
         
' 匿名パイプの作成
Declare Function Api_CreatePipe& Lib "kernel32" Alias "CreatePipe" (phReadPipe&, phWritePipe&, lpPipeAttributes As Any, ByVal nSize&)
        
' ファイルからデータを読み取る
Declare Function Api_ReadFile& Lib "kernel32" Alias "ReadFile" (ByVal hFile&, ByVal lpBuffer$, ByVal nNumberOfBytesToRead&, lpNumberOfBytesRead&, ByVal lpOverlapped As Any)
          
' プロセスの起動
Declare Function Api_CreateProcess& Lib "kernel32" Alias "CreateProcessA" (ByVal AppName&, ByVal ComdLine$, ProcAttr As Any, ThreadAttr As Any, ByVal InheritHand&, ByVal CreationFlags&, ByVal Env&, ByVal CurrentDir&, StartupInfo As Any, ProcInfo As Any)

' オープンされているオブジェクトハンドルをクローズ
Declare Function Api_CloseHandle& Lib "Kernel32" Alias "CloseHandle" (ByVal hObject&)

' パイプの内容を調べる
Declare Function Api_PeekNamedPipe& Lib "kernel32" Alias "PeekNamedPipe" (ByVal hNamedPipe&, lpBuffer As Any, ByVal nBufferSize&, lpBytesRead&, lpTotalBytesAvail&, lpBytesLeftThisMessage&)

' 指定されたカーネルオブジェクトがシグナル状態になるか、指定された時間が経過するまでスレッドをスリープ
Declare Function Api_WaitForSingleObject& Lib "Kernel32" Alias "WaitForSingleObject" (ByVal hHandle&, ByVal dwMilliseconds&)

#define NORMAL_PRIORITY_CLASS &H20      '通常クラス(一般的なプロセス)
#define STARTF_USESTDHANDLES &H100
      
Var Shared Edit1 As Object
Edit1.Attach GetDlgItem("Edit1") : Edit1.SetFontSize 14

'================================================================
'=
'================================================================
Declare Function ExecCmd(cmdline$) As String
Function ExecCmd(cmdline$) As String
    Var pi As PROCESS_INFORMATION
    Var si As STARTUPINFO
    Var sa As SECURITY_ATTRIBUTES
    Var hReadPipe As Long
    Var hWritePipe As Long
    Var L As Long
    Var bSuccess As Long
    Var Buffer As String
    Var lPeekData As Long
    Var txt As String
    Var Ret As Long
    
    sa.nLength = Len(sa)
    sa.bInheritHandle = 1
    sa.lpSecurityDescriptor = 0

    '匿名パイプの作成
    Ret = Api_CreatePipe(hReadPipe, hWritePipe, sa, 0)
   
    If Ret = 0 Then
        A% = MessageBox(GetWindowText, "CreatePipeエラー!", 0, 2)
        Exit Function
    End If

    si.cb = Len(si)
    si.dwFlags = STARTF_USESTDHANDLES
    si.hStdOutput = hWritePipe

    'プロセスの起動(例では、ipconfig.exe)
    Ret = Api_CreateProcess(0, cmdline$, sa, sa, 1, NORMAL_PRIORITY_CLASS, 0, 0, si, pi)

    If Ret <> 0 Then
        Do
            'パイプからデータを取得
            Ret = Api_PeekNamedPipe(hReadPipe, ByVal 0, 0, ByVal 0, lPeekData, ByVal 0)

            If lPeekData > 0 Then
                Buffer = Space$(lPeekData)
                'データの読み取り
                bSuccess = Api_ReadFile(hReadPipe, Buffer, Len(Buffer), L, 0)

                If bSuccess = 1 Then
                    txt = txt & Left$(Buffer, L)
                Else
                    A% = MessageBox(GetWindowText, "ReadFileに失敗!", 0, 2)
                End If
            Else
                bSuccess = Api_WaitForSingleObject(pi.hProcess, 0)

                If bSuccess = 0 Then
                    Exit Do
                End If
            End If

            CallEvent
        Loop
    Else
        A% = MessageBox(GetWindowText, "プロセスエラー!", 0, 2)
    End If

    'ハンドルの解放
    Ret = Api_CloseHandle(pi.hProcess)
    Ret = Api_CloseHandle(pi.hThread)
    Ret = Api_CloseHandle(hReadPipe)
    Ret = Api_CloseHandle(hWritePipe)

    ExecCmd = txt
End Function

'================================================================
'=
'================================================================
Declare Sub Button1_on edecl ()
Sub Button1_on()
    Edit1.SetWindowText ExecCmd("ipconfig.exe")
End Sub

'================================================================
'=
'================================================================
While 1
    WaitEvent
Wend
Stop
End