by イグトランス » 2005年11月15日(火) 22:17
ちなみにリダイレクトの必要さえなければExec "jperl", "c:\prog\hello_world.pl hoge.txt"のようにすればできます。
さて、起動したプログラムが終了したかどうか検出をしたいときには
ShellExecuteやExecは残念ながら使えません。
CreateProcessやShellExecuteExでできるのですが、
後者はたしかABのインクルードファイル内に宣言がないので前者を使ってみます。
しかもCreateProcessにはリダイレクトの機能があります。これを使わないわけにはいきません。
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
#strict
Declare Function CreatePipe Lib "Kernel32" (
ByRef hReadPipe As HANDLE,
ByRef hWritePipe As HANDLE,
ByVal pPipeAttributes As *SECURITY_ATTRIBUTES,
ByVal nSize As DWORD) As Long
Function ExecWithRedirectOutputAndWait(pszCmdLine As BytePtr) As HANDLE
Dim sa As SECURITY_ATTRIBUTES
With sa
.nLength = Len(sa)
.lpSecurityDescriptor = 0
.bInheritHandle = TRUE
End With
Dim hRead As HANDLE, hWrite As HANDLE
If CreatePipe(hRead, hWrite, VarPtr(sa), 0) <> FALSE Then
Dim si As STARTUPINFO, pi As PROCESS_INFORMATION
ZeroMemory(VarPtr(si), Len(si))
With si
.cb = Len(si)
.dwFlags = STARTF_USESTDHANDLES
.hStdInput = 0
.hStdOutput = hWrite
.hStdError = 0 'hWrite
End With
If CreateProcess(0, CMD, ByVal 0, ByVal 0, TRUE, DETACHED_PROCESS, 0, 0, si, pi) Then
CloseHandle(pi.hThread)
WaitForSingleObject(pi.hProcess, INFINITE)
ExecWithRedirectOutputAndWait = hRead
CloseHandle(pi.hProcess)
End If
CloseHandle(hWrite)
If ExecWithRedirectOutputAndWait = 0 Then
CloseHandle(hRead)
End If
End If
End Function
肝はCreateProcessであり、WaitForSingleObjectが終了まで待つという動作を行います。
リダイレクトには「パイプ」を使ってファイルを通さずに直接読み取るようになっています。
たとえばこう使います。(私はPerlはやらないのでjperlの代わりに別のプログラムでテストしましたが)
コード: 全て選択
Dim hHandle As HANDLE
hHandle = ExecWithRedirectOutputAndWait("jperl c:\prog\hello_world.pl hoge.txt")
Dim Buf[256] As Byte, ReadBytes As DWord
ReadFile(hHandle, Buf, Len(Buf), VarPtr(ReadBytes), ByVal 0)
CloseHandle(hHandle)
MessageBox(0, Buf, 0, 0)
これは出力された内容の最初の256文字を読み出すように作ってあります。
と、ここまで書いたところで読み返してみて思ったのですが、
パピヨンさんは正規表現を使いたいがためにPerlを使っているのですよね。
正規表現だけならBREGEXP.DLLを使えばABからでもなんでも使えますよ。
これを考えてみるのもどうでしょうか。
ちなみにリダイレクトの必要さえなければExec "jperl", "c:\prog\hello_world.pl hoge.txt"のようにすればできます。
さて、起動したプログラムが終了したかどうか検出をしたいときには
ShellExecuteやExecは残念ながら使えません。
CreateProcessやShellExecuteExでできるのですが、
後者はたしかABのインクルードファイル内に宣言がないので前者を使ってみます。
しかもCreateProcessにはリダイレクトの機能があります。これを使わないわけにはいきません。
[hide][code]#strict
Declare Function CreatePipe Lib "Kernel32" (
ByRef hReadPipe As HANDLE,
ByRef hWritePipe As HANDLE,
ByVal pPipeAttributes As *SECURITY_ATTRIBUTES,
ByVal nSize As DWORD) As Long
Function ExecWithRedirectOutputAndWait(pszCmdLine As BytePtr) As HANDLE
Dim sa As SECURITY_ATTRIBUTES
With sa
.nLength = Len(sa)
.lpSecurityDescriptor = 0
.bInheritHandle = TRUE
End With
Dim hRead As HANDLE, hWrite As HANDLE
If CreatePipe(hRead, hWrite, VarPtr(sa), 0) <> FALSE Then
Dim si As STARTUPINFO, pi As PROCESS_INFORMATION
ZeroMemory(VarPtr(si), Len(si))
With si
.cb = Len(si)
.dwFlags = STARTF_USESTDHANDLES
.hStdInput = 0
.hStdOutput = hWrite
.hStdError = 0 'hWrite
End With
If CreateProcess(0, CMD, ByVal 0, ByVal 0, TRUE, DETACHED_PROCESS, 0, 0, si, pi) Then
CloseHandle(pi.hThread)
WaitForSingleObject(pi.hProcess, INFINITE)
ExecWithRedirectOutputAndWait = hRead
CloseHandle(pi.hProcess)
End If
CloseHandle(hWrite)
If ExecWithRedirectOutputAndWait = 0 Then
CloseHandle(hRead)
End If
End If
End Function[/code][/hide]
肝はCreateProcessであり、WaitForSingleObjectが終了まで待つという動作を行います。
リダイレクトには「パイプ」を使ってファイルを通さずに直接読み取るようになっています。
たとえばこう使います。(私はPerlはやらないのでjperlの代わりに別のプログラムでテストしましたが)
[code]Dim hHandle As HANDLE
hHandle = ExecWithRedirectOutputAndWait("jperl c:\prog\hello_world.pl hoge.txt")
Dim Buf[256] As Byte, ReadBytes As DWord
ReadFile(hHandle, Buf, Len(Buf), VarPtr(ReadBytes), ByVal 0)
CloseHandle(hHandle)
MessageBox(0, Buf, 0, 0)[/code]
これは出力された内容の最初の256文字を読み出すように作ってあります。
と、ここまで書いたところで読み返してみて思ったのですが、
パピヨンさんは正規表現を使いたいがためにPerlを使っているのですよね。
正規表現だけならBREGEXP.DLLを使えばABからでもなんでも使えますよ。
これを考えてみるのもどうでしょうか。