Access911.net   |   a9BBS   |   OTaA System  
  搜索文章:  
Access911欢迎您光临  
   主页      上传      繁體版       论坛     
设为首页  |  加入收藏   
  
你现在的位置:文章索引 -> 文章分类 -> API  
 首页|  近日更新|  下载  |  文章索引  |  搜索|  术语|  承接工程|  
 
系统正在加载内容,请耐心等待...
 
 查询
 窗体
 报表
 
 
 VBA
 函数
 ADO/DAO/ADO.NET
 API
 ADP
 安全
 发布
 OA
 ASP/ASP.NET
 其他语言
 控件
 DELPHI
 C#/.Net
 本站
 其他
 小例程
 常用软件
 参考文档
 业主作品
 网友大作
 
 
友情链接
 access911.net
 
访问人次
 1701857
 
站长 E-Mail
 net911@sina.com
 access911@gmail.com
 
RSS 订阅

显示附加信息 >>>

如何通过管道返回shell命令行的执行结果?

作者:cg1  摘自:access911.net  :cg1  更新日期:2011-8-7  浏览人次:

 

问题:

如果要在 ACCESS  VBA 中执行 ipconfig /all 等命令,一般会用  ipconfig /all > c:\a.txt 这种管道命令来重定向输出结果,然后用 VBA 去分析这个 .TXT 文件,是否能够直接输出结果到字符串呢?

 

回答:


Option Explicit
Const NORMAL_PRIORITY_CLASS = &H20&
'Return code/value Description
'ABOVE_NORMAL_PRIORITY_CLASS
'0x00008000 Process that has priority above NORMAL_PRIORITY_CLASS but below HIGH_PRIORITY_CLASS.
'
'BELOW_NORMAL_PRIORITY_CLASS
'0x00004000 Process that has priority above IDLE_PRIORITY_CLASS but below NORMAL_PRIORITY_CLASS.
'
'HIGH_PRIORITY_CLASS
'0x00000080 Process that performs time-critical tasks that must be executed immediately for it to run correctly. The threads of a high-priority class process preempt the threads of normal or idle priority class processes. An example is the Task List, which must respond quickly when called by the user, regardless of the load on the operating system. Use extreme care when using the high-priority class, because a high-priority class CPU-bound application can use nearly all available cycles.
'
'IDLE_PRIORITY_CLASS
'0x00000040 Process whose threads run only when the system is idle and are preempted by the threads of any process running in a higher priority class. An example is a screen saver. The idle priority class is inherited by child processes.
'
'NORMAL_PRIORITY_CLASS
'0x00000020 Process with no special scheduling needs.
'
'REALTIME_PRIORITY_CLASS
'0x00000100 Process that has the highest possible priority. The threads of a real-time priority class process preempt the threads of all other processes, including operating system processes performing important tasks. For example, a real-time process that executes for more than a very brief interval can cause disk caches not to flush or cause the mouse to be unresponsive.

 
Const STARTF_USESTDHANDLES = &H100&
Const STARTF_USESHOWWINDOW = &H1

'Value Meaning
'STARTF_FORCEONFEEDBACK
'0x00000040 Indicates that the cursor is in feedback mode for two seconds after CreateProcess is called. The Working in Background cursor is displayed (see the Pointers tab in the Mouse control panel utility).
'
'If during those two seconds the process makes the first GUI call, the system gives five more seconds to the process. If during those five seconds the process shows a window, the system gives five more seconds to the process to finish drawing the window.
'
'The system turns the feedback cursor off after the first call to GetMessage, regardless of whether the process is drawing.
'
'STARTF_FORCEOFFFEEDBACK
'0x00000080 Indicates that the feedback cursor is forced off while the process is starting. The Normal Select cursor is displayed.
'
'STARTF_PREVENTPINNING
'0x00002000 Indicates that any windows created by the process cannot be pinned on the taskbar.
'
'This flag must be combined with STARTF_TITLEISAPPID.
'
'STARTF_RUNFULLSCREEN
'0x00000020 Indicates that the process should be run in full-screen mode, rather than in windowed mode.
'
'This flag is only valid for console applications running on an x86 computer.
'
'STARTF_TITLEISAPPID
'0x00001000 The lpTitle member contains an AppUserModelID. This identifier controls how the taskbar and Start menu present the application, and enables it to be associated with the correct shortcuts and Jump Lists. Generally, applications will use the SetCurrentProcessExplicitAppUserModelID and GetCurrentProcessExplicitAppUserModelID functions instead of setting this flag. For more information, see Application User Model IDs.
'
'If STARTF_PREVENTPINNING is used, application windows cannot be pinned on the taskbar. The use of any AppUserModelID-related window properties by the application overrides this setting for that window only.
'
'This flag cannot be used with STARTF_TITLEISLINKNAME.
'
'STARTF_TITLEISLINKNAME
'0x00000800 The lpTitle member contains the path of the shortcut file (.lnk) that the user invoked to start this process. This is typically set by the shell when a .lnk file pointing to the launched application is invoked. Most applications will not need to set this value.
'
'This flag cannot be used with STARTF_TITLEISAPPID.
'
'STARTF_USECOUNTCHARS
'0x00000008 The dwXCountChars and dwYCountChars members contain additional information.
'
'STARTF_USEFILLATTRIBUTE
'0x00000010 The dwFillAttribute member contains additional information.
'
'STARTF_USEHOTKEY
'0x00000200 The hStdInput member contains additional information.
'
'This flag cannot be used with STARTF_USESTDHANDLES.
'
'STARTF_USEPOSITION
'0x00000004 The dwX and dwY members contain additional information.
'
'STARTF_USESHOWWINDOW
'0x00000001 The wShowWindow member contains additional information.
'
'STARTF_USESIZE
'0x00000002 The dwXSize and dwYSize members contain additional information.
'
'STARTF_USESTDHANDLES
'0x00000100 The hStdInput, hStdOutput, and hStdError members contain additional information.
'
'If this flag is specified when calling one of the process creation functions, the handles must be inheritable and the function's bInheritHandles parameter must be set to TRUE. For more information, see Handle Inheritance.
'
'If this flag is specified when calling the GetStartupInfo function, these members are either the handle value specified during process creation or INVALID_HANDLE_VALUE.
'
'Handles must be closed with CloseHandle when they are no longer needed.
'
'This flag cannot be used with STARTF_USEHOTKEY.
'

Private Type SECURITY_ATTRIBUTES
    nLength As Long
    lpSecurityDescriptor As Long
    bInheritHandle As Long
End Type
Private Type STARTUPINFO
    cb As Long
    lpReserved As Long
    lpDesktop As Long
    lpTitle As Long
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCountChars As Long
    dwYCountChars As Long
    dwFillAttribute As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As Long
    hStdInput As Long
    hStdOutput As Long
    hStdError As Long
End Type
Private Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessID As Long
    dwThreadID As Long
End Type
Private Declare Function CreatePipe Lib "kernel32" (phReadPipe As Long, _
    phWritePipe As Long, lpPipeAttributes As SECURITY_ATTRIBUTES, _
    ByVal nSize As Long) As Long
Private Declare Function CreateProcess Lib "kernel32" Alias _
    "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, _
    lpProcessAttributes As SECURITY_ATTRIBUTES, lpThreadAttributes As SECURITY_ATTRIBUTES, _
    ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, _
    ByVal lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, _
    lpProcessInformation As PROCESS_INFORMATION) As Long
Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, _
    ByVal lpBuffer As String, ByVal nNumberOfBytesToRead As Long, _
    lpNumberOfBytesRead As Long, ByVal lpOverlapped As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

'在这里执行
Function RunTest()
    'Debug.Print ShellResult("cmd /c dir c:\")
    Debug.Print ShellResult("ipconfig /all")
End Function

'可以执行通过shell执行的命令,并将结果以字符串方式返回。请注意,执行cmd内部命令时请用 “cmd /c dir c:\” 这样的形式。
Public Function ShellResult(ByVal CommandLine As String) As String
    Dim Proc As PROCESS_INFORMATION '进程信息
    Dim Start As STARTUPINFO '启动信息
    Dim SecAttr As SECURITY_ATTRIBUTES '安全属性
    Dim hReadPipe As Long '读取管道句柄
    Dim hWritePipe As Long '写入管道句柄
    Dim lngBytesRead As Long '读出数据的字节数
    Dim strBuffer As String * 256 '读取管道的字符串buffer
    Dim Command As String 'DOS命令
    Dim ret As Long 'API函数返回值
    Dim lpOutputs As String '读出的最终结果
    
    '设置安全属性
    With SecAttr
        .nLength = LenB(SecAttr)
        .bInheritHandle = True
        .lpSecurityDescriptor = 0
    End With
    
    '创建管道
    ret = CreatePipe(hReadPipe, hWritePipe, SecAttr, 0)
    If ret = 0 Then
        MsgBox "无法创建管道", vbExclamation, "错误"
        Exit Function
    End If
    '设置进程启动前的信息
    With Start
        .cb = LenB(Start)
        .dwFlags = STARTF_USESHOWWINDOW Or STARTF_USESTDHANDLES
        .hStdOutput = hWritePipe '设置输出管道
        .hStdError = hWritePipe '设置错误管道
    End With
    
    '启动进程
    'Command = Getwinsys & "ipconfig.exe /all" 'DOS进程以ipconfig.exe为例
    'Command = Getwinsys & "tracert www.google.com" 'DOS进程以ipconfig.exe为例

    Command = Getwinsys & CommandLine
    ret = CreateProcess(vbNullString, Command, SecAttr, SecAttr, True, _
        NORMAL_PRIORITY_CLASS, ByVal 0, vbNullString, Start, Proc)
    If ret = 0 Then
        MsgBox "无法启动新进程", vbExclamation, "错误"
        Exit Function
    End If
    '因为无需写入数据,所以先关闭写入管道。而且这里必须关闭此管道,否则将无法读取数据
    ret = CloseHandle(hWritePipe)
    '从输出管道读取数据,每次最多读取256字节
    Do
        ret = ReadFile(hReadPipe, strBuffer, 256, lngBytesRead, ByVal 0)
        'If Len(lpOutputs) > 0 Then
        '    Debug.Print Right(lpOutputs, 1), Asc(Right(lpOutputs, 1)), Right(lpOutputs, 7)
        'End If
        lpOutputs = lpOutputs & Left(strBuffer, lngBytesRead)
        strBuffer = ""
        DoEvents
    Loop While (ret <> 0) '当ret=0时说明ReadFile执行失败,已经没有数据可读了
    '读取操作完成,关闭各句柄

    ret = CloseHandle(Proc.hProcess)
    ret = CloseHandle(Proc.hThread)
    ret = CloseHandle(hReadPipe)
    'Debug.Print lpOutputs           '输出结果
    ShellResult = lpOutputs
    'MsgBox lpOutputs, vbInformation, "结果"
End Function

Public Function Getwinsys() As String
    Dim aa As String, jj As String
    aa = Environ("ComSpec")
    jj = InStrRev(aa, "\")
    Getwinsys = Trim(Mid(aa, 1, jj))
End Function


 


本站文章旨在为该问题提供解决思路及关键性代码,并不能完成应该由网友自己完成的所有工作,请网友在仔细看文章并理解思路的基础上举一反三、灵活运用。

access911.net 原创文章,作者本人对文章保留一切权利。
如需转载必须征得作者同意并注明本站链接

 

 
相关文章
     没有手动相关文章
     新手来看:查不到帮助的来看:命令行启动
     方法二:等待调用外部程序执行完毕
     如何解决shell执行外部程序的等待问题?(同步/异步)
 
评论
     查看或发表更多的评论,请单击这里。
 
 
 
 
 
   
  Access911.net   |   a9BBS   |   OTaA System   |
建站日期:2000年4月2日  |  设计施工:陈格 ( access911 & cg1 )
 Copyright © 2000 - 2003 COMET, 陈格 保留所有权利