Vb6 壳牌过程';Visual Basic 6中的标准输出读数

Vb6 壳牌过程';Visual Basic 6中的标准输出读数,vb6,process,stdout,polling,Vb6,Process,Stdout,Polling,首先,让我说我不是一个VisualBasic6专家 我的需要是: 从VB6客户端代码启动exeenal.exe文件 等待进程完成,并在执行过程中“动态”读取来自其标准输出的消息(以便我可以在文本文件小部件或类似文件上打印它) 我想知道是否有可能在VB6中实现这一点……在互联网上搜索了很长时间后,我什么都没找到。找到了很多关于如何使用Shell函数的示例,但它似乎迫使我在进程执行结束时一次读取所有标准输出,但我希望在进程中找到可用的“新”消息时轮询这些消息 非常感谢您提供任何代码片段/建议/参

首先,让我说我不是一个VisualBasic6专家

我的需要是:

  • 从VB6客户端代码启动exeenal.exe文件
  • 等待进程完成,并在执行过程中“动态”读取来自其标准输出的消息(以便我可以在文本文件小部件或类似文件上打印它)
我想知道是否有可能在VB6中实现这一点……在互联网上搜索了很长时间后,我什么都没找到。找到了很多关于如何使用
Shell
函数的示例,但它似乎迫使我在进程执行结束时一次读取所有标准输出,但我希望在进程中找到可用的“新”消息时轮询这些消息

非常感谢您提供任何代码片段/建议/参考

提前谢谢

使用
CreatePipe()
创建一个匿名管道,您可以将其传递到
CreateProcess()
。 然后,您可以根据需要从该管道读取数据(使用轮询或重叠/异步I/O)

这将为您提供足够的信息以找到一个好的示例。

使用
CreatePipe()
创建一个匿名管道,您可以将其传递到
CreateProcess()
。 然后,您可以根据需要从该管道读取数据(使用轮询或重叠/异步I/O)


这将为您提供足够的信息,以便找到一个好的示例。

您还可以创建一个包含所有需要运行的命令的批处理文件,然后通过执行以下命令从VB6调用批处理文件

 Shell "C:\YourPath\BatchFileName.bat > OutputFileName.txt"   'Overwrites OutputFilename.txt everytime
一旦执行该操作,然后打开
OutputFileName.txt
,您将找到批处理过程中生成的所有消息和输出。然后,您可以在VB6中通过一个简单的
打开“filename”以作为#1

您还应该注意,如果使用双大于号,则不会在每次批处理运行时都覆盖输出文件,而是在输出文件后面追加新的输出行

 Shell "C:\YourPath\BatchFileName.bat >> OutputFileName.txt"    'This will append to OutputFileName.txt

您还可以创建一个批处理文件,其中包含需要运行的所有命令,然后通过执行以下命令从VB6调用批处理文件

 Shell "C:\YourPath\BatchFileName.bat > OutputFileName.txt"   'Overwrites OutputFilename.txt everytime
一旦执行该操作,然后打开
OutputFileName.txt
,您将找到批处理过程中生成的所有消息和输出。然后,您可以在VB6中通过一个简单的
打开“filename”以作为#1

您还应该注意,如果使用双大于号,则不会在每次批处理运行时都覆盖输出文件,而是在输出文件后面追加新的输出行

 Shell "C:\YourPath\BatchFileName.bat >> OutputFileName.txt"    'This will append to OutputFileName.txt

这是您想要的函数。声明API(CreatePipe、CreateProcessA、CloseHandle等)、类型(流程信息、STARTUPINFO、安全属性)和常量(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
Public Function ExecuteCommand(ByVal命令行作为字符串,可选bShowWindow作为Boolean=False,可选sCurrentDir作为字符串)作为字符串
Dim proc As PROCESS_INFORMATION’由CreateProcessA填写的过程信息
Dim ret As Long“Long变量,用于获取
'API函数
Dim start As STARTUPINFO的启动信息传递给CreateProceeeA
'功能
Dim sa As SECURITY_属性的安全属性传递给
'CreateProcessA函数
Dim hread Pipe As Long“读取由CreatePipe创建的管道句柄
将hWritePipe设置为长“写入由CreatePipe创建的Pite句柄”
Dim LNGBytes读取为从读取管道句柄读取的“长”字节量
将strBuff设置为字符串*256'字符串缓冲区读取管道
'如果参数不是空的,请更新命令行属性
如果Len(命令行)>0,则
mCommand=命令行
如果结束
'如果命令行为空,则退出时显示错误消息
如果Len(mCommand)=0,则
ApplicationEventLogError“模块ModPipedOut的过程ExecuteCommand中的命令行为空。”
退出功能
如果结束
'创建管道
sa.nLength=Len(sa)
sa.bInheritHandle=1&
sa.lpSecurityDescriptor=0&
ret=CreatePipe(线程管道,hWritePipe,sa,0)
如果ret=0,则
'如果在管道创建退出期间发生错误
Debug.Print“CreatePipe失败。错误:&Err.LastDllError&”(“&ReturnError(Err.LastDllError))
退出功能
如果结束
'启动命令行应用程序
start.cb=Len(开始)
start.dwFlags=STARTF\u USESTDHANDLES或STARTF\u USESHOWWINDOW
'将StdOutput和StdError输出设置为相同的写入管道句柄
start.hStdOutput=hWritePipe
start.hStdError=hWritePipe
'start.hStdInput=hInReadPipe
如果是显示窗口,那么
start.wShowWindow=SW\u SHOWNORMAL
其他的
start.wShowWindow=SW\u HIDE
如果结束
'执行命令
如果Len(sCurrentDir)=0,则
ret&=CreateProcessA(0&,mCommand,sa,sa,1&_
普通\u优先级\u类,0&,vbNullString,start,proc)
其他的
ret&=CreateProcessA(0&,mCommand,sa,sa,1&_
正常\u优先级\u类,0&,sCurrentDir,开始,过程)
如果结束
如果ret 1那么
'如果找不到命令。。。。
Debug.Print“在过程ExecuteCommand中找不到文件或命令”
退出功能
如果结束
“现在我们可以……必须关闭管道
ret=闭合手柄(hWritePipe)
'ret=闭合手柄(hInReadPipe)
mOutputs=vbNullString
'读取ReadPipe句柄
做
ret=ReadFile(线程管道,strBuff,256,千兆字节