首先,我要说我不是Visual Basic 6专家......
我的需要是:
我想知道是否有可能在VB6中这样做...在互联网上长时间搜索之后我没有想出任何东西。找到了很多关于如何使用Shell
函数的例子,但它似乎迫使我在进程执行结束时一次性读取stdout,但我想在流程中查询“新鲜”消息因为它们可用。
非常感谢任何代码段/建议/参考。
提前致谢!
答案 0 :(得分:6)
使用CreatePipe()
创建一个可以传递给CreateProcess()
的匿名管道。
然后,您可以根据需要从此管道中读取(使用轮询或重叠/异步I / O.
这应该为您提供足够的信息以找到一个好的例子。
答案 1 :(得分:4)
您始终可以使用Exec method of WshShell来完成这项工作。
我更喜欢使用自行开发的基于API的解决方案cExec.cls比Bob Riemersma的用户控件简单得多(但不是那么通用)。
答案 2 :(得分:2)
您还可以创建一个批处理文件,其中包含您需要运行的所有命令,然后从VB6执行
调用批处理文件 Shell "C:\YourPath\BatchFileName.bat > OutputFileName.txt" 'Overwrites OutputFilename.txt everytime
执行该操作后,再打开OutputFileName.txt
,您将找到批处理过程中生成的所有消息和输出。然后,您可以使用简单的open "filename" for input as #1
您还应注意,如果使用Double GreaterThan符号,则每次批处理运行时都不会覆盖输出文件。相反,它会附加新的输出行。
Shell "C:\YourPath\BatchFileName.bat >> OutputFileName.txt" 'This will append to OutputFileName.txt
答案 3 :(得分:1)
这是您想要的功能。声明API(CreatePipe,CreateProcessA,CloseHandle等),类型(PROCESS_INFORMATION,STARTUPINFO,SECURITY_ATTRIBUTES)常量(STARTF_USESTDHANDLES,STARF_USESHOWWINDOW等)的练习留给读者。
Public Function ExecuteCommand(ByVal CommandLine As String, Optional bShowWindow As Boolean = False, Optional sCurrentDir As String) As String
Dim proc As PROCESS_INFORMATION 'Process info filled by CreateProcessA
Dim ret As Long 'long variable for get the return value of the
'API functions
Dim start As STARTUPINFO 'StartUp Info passed to the CreateProceeeA
'function
Dim sa As SECURITY_ATTRIBUTES 'Security Attributes passeed to the
'CreateProcessA function
Dim hReadPipe As Long 'Read Pipe handle created by CreatePipe
Dim hWritePipe As Long 'Write Pite handle created by CreatePipe
Dim lngBytesRead As Long 'Amount of byte read from the Read Pipe handle
Dim strBuff As String * 256 'String buffer reading the Pipe
'if the parameter is not empty update the CommandLine property
If Len(CommandLine) > 0 Then
mCommand = CommandLine
End If
'if the command line is empty then exit whit a error message
If Len(mCommand) = 0 Then
ApplicationEventLogError "Command Line empty in procedure ExecuteCommand of module modPipedOutput."
Exit Function
End If
'Create the Pipe
sa.nLength = Len(sa)
sa.bInheritHandle = 1&
sa.lpSecurityDescriptor = 0&
ret = CreatePipe(hReadPipe, hWritePipe, sa, 0)
If ret = 0 Then
'If an error occur during the Pipe creation exit
Debug.Print "CreatePipe failed. Error: " & Err.LastDllError & " (" & ReturnError(Err.LastDllError)
Exit Function
End If
'Launch the command line application
start.cb = Len(start)
start.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW
'set the StdOutput and the StdError output to the same Write Pipe handle
start.hStdOutput = hWritePipe
start.hStdError = hWritePipe
' start.hStdInput = hInReadPipe
If bShowWindow Then
start.wShowWindow = SW_SHOWNORMAL
Else
start.wShowWindow = SW_HIDE
End If
'Execute the command
If Len(sCurrentDir) = 0 Then
ret& = CreateProcessA(0&, mCommand, sa, sa, 1&, _
NORMAL_PRIORITY_CLASS, 0&, vbNullString, start, proc)
Else
ret& = CreateProcessA(0&, mCommand, sa, sa, 1&, _
NORMAL_PRIORITY_CLASS, 0&, sCurrentDir, start, proc)
End If
If ret <> 1 Then
'if the command is not found ....
Debug.Print "File or command not found in procedure ExecuteCommand"
Exit Function
End If
'Now We can ... must close the hWritePipe
ret = CloseHandle(hWritePipe)
' ret = CloseHandle(hInReadPipe)
mOutputs = vbNullString
'Read the ReadPipe handle
Do
ret = ReadFile(hReadPipe, strBuff, 256, lngBytesRead, 0&)
mOutputs = mOutputs & Left$(strBuff, lngBytesRead)
'Send data to the object via ReceiveOutputs event
Loop While ret <> 0
'Close the opened handles
Call CloseHandle(proc.hProcess)
Call CloseHandle(proc.hThread)
Call CloseHandle(hReadPipe)
'Return the Outputs property with the entire DOS output
ExecuteCommand = mOutputs
End Function