進程通信之匿名管道VFB使用說明

  勇芳 2018-5-19 5262

匿名管道可以用來父進程與子進程通信,非父子關系的無法用匿名管道通信

匿名管道功能單一,使用簡單,用很少代碼即可。

我們用代碼啟動一個軟件,那么被啟動的軟件成為我們軟件的子進程了

準備工作:

#include Once "fbthread.bi"  '需要多線程
Type PipeStruct '
    hPipeInputRead As HANDLE   '數據輸入管道  
    hPipeInputWrite As HANDLE  '數據輸入管道  
    hPipeOutputRead As HANDLE   '數據輸出管道  
    hPipeOutputWrite As HANDLE  '數據輸出管道  
    bConsole As PROCESS_INFORMATION    '控制臺 
End Type
Dim Shared pipe As PipeStruct '保存管道的變量

一、建立匿名管道,因為管道是單向的,要雙向通信,必須建立2個

  Dim Sa As SECURITY_ATTRIBUTES
  With Sa '設置管道句柄安全屬性
      .nLength = SizeOf(SECURITY_ATTRIBUTES)
      .bInheritHandle = True  '必須為TRUE
      .lpSecurityDescriptor = 0
  End With
  '數據輸入管道
  CreatePipe(@pipe.hPipeInputRead, @pipe.hPipeInputWrite, @sa, 0)
  '數據輸出管道
  CreatePipe(@pipe.hPipeOutputRead, @pipe.hPipeOutputWrite, @sa, 0)

二、啟動子進程,以 CMD 為例題,當然可以是任意軟件,而且隱藏掉軟件,在背后偷偷運行

  Dim si As STARTUPINFO, CmdStr As String
  '設置進程的啟動信息,這是一個輸入參數
  si.cb = SizeOf(STARTUPINFO)
  GetStartupInfo(@si)
  si.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW '這個必須設置,否則仍將顯示窗口
  si.hStdOutput = pipe.hPipeOutputWrite '輸出由標準輸出 -> 輸出到管道 
  si.hStdError = pipe.hPipeOutputWrite  '輸出由標準輸出 -> 輸出到管道
  Si.hStdInput = pipe.hPipeInputRead    '輸入由標準輸入 -> 從管道中讀取
  si.wShowWindow = SW_HIDE  '隱藏子進程
  '使用剛才設置的各個參數創建隱秘的進程
  '此進程將把ping程序運行的結果寫到管道
  CreateProcessA(Null, "CMD", Null, Null, True, Null, Null, Null, @Si, @pipe.bConsole)

三、啟動讀取內容線程,不用多線程會發生堵塞。讀取來自子進程,子讀父,需要稍微改改即可

Threaddetach ThreadCreate(Cast(Any Ptr, @PipeLineInput), @pipe) '讀取無內容時線程會被掛起,因此必須用多線程
Sub PipeLineInput(ByRef pipe As PipeStruct) '讀取內容,的線程
  '從管道讀取上述進程的輸出,并顯示于界面
  Dim bRet As WINBOOL, buffer As ZString * 1024, dwBytesRead As Long
  Dim BtRead As Long, BtTotal As Long, BtLeft As Long, OutData As String, ff As Long
  Dim tt As String 
  Do
      bRet = ReadFile(pipe.hPipeOutputRead, @buffer, 1024, @dwBytesRead, Null)
      If bRet=0 Then Exit Do
      If dwBytesRead > 0 Then
         If Left(buffer,dwBytesRead)="終止引擎" Then Exit Do
          OutData &= Left(buffer,dwBytesRead)
          Do
              ff = InStr(OutData, vbCrLf)
              If ff = 0 Then Exit Do
              tt=FF_Control_GetText(HWND_FORM1_TEXT2)  此處要改,用于輸出獲取的內容
'              Print  Mid(OutData, 1, ff -1)           此處要改,用于輸出獲取的內容
              tt &=vbCrLf & Mid(OutData, 1, ff -1)     此處要改,用于輸出獲取的內容
              FF_Control_SetText HWND_FORM1_TEXT2,tt   此處要改,用于輸出獲取的內容
              OutData = Mid(OutData, ff + 2)
          Loop
      End If
      Sleep 100
  Loop
'  Print "完成了........"
End Sub

四、發送內容,這里是父發給子的,子發給父的稍微改改即可,就是那個句柄

Sub PipeLineOutput(ByRef pipe As PipeStruct, szLineStr As String) '發送
  Dim Buflen As Long, BtWritten As Long, rtn As Long
  rtn = WriteFile(pipe.hPipeInputWrite, StrPtr(szLineStr), Len(szLineStr), @BtWritten, Null)
'  Print rtn, BtWritten
End Sub

五、關閉管道,結束子進程

Sub PipeClose(ByRef pipe As PipeStruct) '關閉引擎
  Dim Buflen As Long, BtWritten As Long, rtn As Long, szLineStr As String
  szLineStr = "終止引擎"  '為了讓線程退出,只有退了,才可以終止引擎
  rtn = WriteFile(pipe.hPipeOutputWrite, StrPtr(szLineStr), Len(szLineStr), @BtWritten, Null)
  Sleep 10 '留給時間給線程退出 
  CloseHandle pipe.hPipeInputRead
  CloseHandle pipe.hPipeInputWrite
  CloseHandle pipe.hPipeOutputRead
  CloseHandle pipe.hPipeOutputWrite
  CloseHandle pipe.bConsole.hThread
  CloseHandle pipe.bConsole.hProcess
  ProcessKill(pipe.bConsole.dwProcessId) 終止進程
End Sub


六、子進程獲取父進程發來的管道句柄,有了句柄,在子進程里,仿照上面的寫法,應該不難寫出來吧。

  Print GetStdHandle(STD_INPUT_HANDLE)   'Si.hStdInput  用來讀取父進程發來的內容
  Print GetStdHandle(STD_OUTPUT_HANDLE)  'si.hStdOutput 用來發送給父進程內容
  Print GetStdHandle(STD_ERROR_HANDLE)   'si.hStdError


以上是為雙向通信而寫,假如單向,就只搞一個通道即可。


注:本例題源碼下載,請進 B語言編程群:78458582  




因國家互聯網安全管理要求,關閉回帖功能。大家需要留言,請使用【勇芳軟件客服】即時聯系勇芳點此打開->>勇芳軟件客服
返回
聯系勇芳
一个人看的www视频播放中文_2012中文字幕电影_亚洲国产成人高清在线观看_中文字幕天堂最新版在线网