どうも、はじめまして。
ABでGUIアプリを創って、それと他のコンソールアプリと連携させたいと
考えています。具体的には、ABからコンソールアプリを起動して、
そのコンソールアプリの標準入力にデータを送り、標準出力からの
データをAB側に返す、というものです(双方向パイプ)。
どのような命令(もしくはAPI)を使えばよいのでしょうか?
DLLを使って連携させる方法はできると思うのですが、どうしても
都合上パイプを使って連携させたいのです。
ヘルプやネットのデータを参照したのですが、どうも上手くいかなかったので
質問させて頂きました。
パイプについて
使い方は「名前付きパイプ」で検索すると沢山出ます
標準入出力を利用したいだけであれば名前付きパイプである必要性はないです
CreateProcessで受け渡しができるので
以下匿名パイプでコマンドライン(cmd.exe)とやりとりするサンプル
面倒だったので外しました
標準入出力を利用したいだけであれば名前付きパイプである必要性はないです
CreateProcessで受け渡しができるので
以下匿名パイプでコマンドライン(cmd.exe)とやりとりするサンプル
[ここをクリックすると内容が表示されます]
本当は標準エラー出力ハンドルもチェックすべきですがコード: 全て選択
'WaitForSingleObject用
Const WAIT_OBJECT_0 = 0
'宣言
Declare Function CreatePipe Lib "kernel32" (ByRef hReadPipe As HANDLE,ByRef hWritePipe As HANDLE,ByRef PipeAttributes As SECURITY_ATTRIBUTES,nSize As DWord) As Long
Declare Function PeekNamedPipe Lib "kernel32" (hNamedPipe As HANDLE,lpBuffer As VoidPtr,nBufferSize As DWord,lpBytesRead As *DWord,lpTotalBytesAvail As *DWord,lpBytesLeftThisMessage As *DWord) As Long
'パイプ
Dim Inp_StdIn_Read As HANDLE,Inp_StdIn_Write As HANDLE' 標準入力パイプ (データの向き)Server → Client
Dim Inp_StdOut_Read As HANDLE,Inp_StdOut_Write As HANDLE' 標準出力パイプ S ← C
Dim Inp_ErrOut_Read As HANDLE,Inp_ErrOut_Write As HANDLE' 標準エラー出力パイプ S ← C
'パイプのセキュリティ設定
Dim sa As SECURITY_ATTRIBUTES
sa.nLength = SizeOf(SECURITY_ATTRIBUTES)
sa.lpSecurityDescriptor = NULL
sa.bInheritHandle = TRUE' 継承を許可する
'パイプ作成
CreatePipe(Inp_StdIn_Read,Inp_StdIn_Write,sa,0)
CreatePipe(Inp_StdOut_Read,Inp_StdOut_Write,sa,0)
CreatePipe(Inp_ErrOut_Read,Inp_ErrOut_Write,sa,0)
'子プロセス起動
Dim si As STARTUPINFO,pi As PROCESS_INFORMATION
si.cb = SizeOf(STARTUPINFO)
si.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW
si.wShowWindow = SW_HIDE
si.hStdInput = Inp_StdIn_Read
si.hStdOutput = Inp_StdOut_Write
si.hStdError = Inp_ErrOut_Write
CreateProcess(0,"cmd",ByVal NULL,ByVal NULL,TRUE,0,NULL,NULL,si,pi)
'読み書きに使う変数
Dim Size As DWord,buf[32] As Byte,Ws As DWord
'標準入力にコマンドを流す
WriteFile(Inp_StdIn_Write,Ex"dir c:\\\n",lstrlen(Ex"dir c:\\\n"),VarPtr(Ws),ByVal NULL)
Do
'標準出力パイプにデータがあるかチェック
PeekNamedPipe(Inp_StdOut_Read,NULL,0,NULL,VarPtr(Size),NULL)
'データがあれば読んで表示
If Size>0 Then
ReadFile(Inp_StdOut_Read,buf,32,VarPtr(Size),ByVal 0)
buf[Size] = 0
Print MakeStr(buf);
End If
'無ければ終了コマンドを流す
If Size=0 Then WriteFile(Inp_StdIn_Write,Ex"exit\n",lstrlen(Ex"exit\n"),VarPtr(Ws),ByVal NULL)
'プロセスが終了するとWaitForSingleObjectはWAIT_OBJECT_0返す
Loop Until WaitForSingleObject(pi.hProcess,0)=WAIT_OBJECT_0 And Size=0
'プロセスハンドルを閉じる
CloseHandle(pi.hProcess)
'パイプを閉じる
CloseHandle(Inp_StdIn_Read)
CloseHandle(Inp_StdIn_Write)
CloseHandle(Inp_StdOut_Read)
CloseHandle(Inp_StdOut_Write)
CloseHandle(Inp_ErrOut_Read)
CloseHandle(Inp_ErrOut_Write)
面倒だったので外しました
ありがとうございました!
わざわざコードまでつけて頂き、本当にありがとうございます!
いただいたコードにより、私のコンソールアプリとABとでデータ通信が
行えました。
後は、自分なりに試行錯誤しつつ、改良してみます。
どうも、ありがとうございました!
いただいたコードにより、私のコンソールアプリとABとでデータ通信が
行えました。
後は、自分なりに試行錯誤しつつ、改良してみます。
どうも、ありがとうございました!