【问题标题】:WScript Command - Run Minimized? (MSAccess/VBA)WScript 命令 - 最小化运行? (MSAccess/VBA)
【发布时间】:2018-01-23 18:28:09
【问题描述】:

我正在对用户选择的服务器 IP 执行快速 PING 以确认它是可访问的。

以下代码完全符合我的需要,除了我想避免命令外壳窗口的快速闪烁。

我需要修改什么来最小化那个讨厌的 CMD 窗口?

SystemReachable (myIP)

If InStr(myStatus, "Reply") > 0 Then
    ' IP is Confirmed Reachable
Else
    ' IP is Not Reachable
End If

''''''''''''''''''''''
Function SystemReachable(ByVal strIP As String)

Dim oShell, oExec As Variant
Dim strText, strCmd As String

strText = ""
strCmd = "ping -n 1 -w 1000 " & strIP

Set oShell = CreateObject("WScript.Shell")
Set oExec = oShell.Exec(strCmd)

Do While Not oExec.StdOut.AtEndOfStream
    strText = oExec.StdOut.ReadLine()
    If InStr(strText, "Reply") > 0 Then
        myStatus = strText
        Exit Do
    Else
        myStatus = ""
    End If
Loop

End Function

【问题讨论】:

  • 看到了那个方法,但没有奢侈的重定向到一个文件 - 多个用户。希望保持标准输出方法。会继续寻找 thx
  • 回复:“不要奢侈地重定向到一个文件 - 多个用户” - 这是将从数据库前端执行的操作,而您 确保每个用户都有自己的本地前端副本,对吧...?
  • 是的,正在重新考虑。见下文,创建一个文件。

标签: ms-access vba


【解决方案1】:

这个问题可能有点老了,但我认为这个答案可能仍然可以提供帮助。 (用 Excel VBA 测试,用 Access 无法测试)

WshShell.Exec 方法允许使用 .StdIn、.StdOut 和 .StdErr 函数来写入和读取控制台窗口。 WshShell.Run 方法不允许此功能,因此出于某些目的需要使用 Exec。

虽然确实没有内置函数来最小化或隐藏启动 Exec 方法,但您可以使用 API 快速找到 Exec 窗口 hwnd 并最小化/隐藏它。

我下面的脚本从 Exec 对象中获取 ProcessID 来查找窗口的 Hwnd。然后,您可以使用 Hwnd 设置窗口的显示状态。

根据我对 Excel 2007 VBA 的测试,在大多数情况下,我什至看不到窗口...在某些情况下,它可能会在几毫秒内可见,但只会出现快速闪烁或闪烁...注意:我有使用 SW_MINIMIZE 的结果比我使用 SW_HIDE 的效果更好,但你可以尝试一下。

我添加了 TestRoutine Sub 以展示如何使用“HideWindow”功能的示例。 'HideWindow' 函数使用 'GetHwndFromProcess' 函数从 ProcessID 中获取窗口 hwnd。

将以下内容放入模块中...

Option Explicit
'   ShowWindow() Commands
Public Const SW_HIDE = 0
Public Const SW_MINIMIZE = 6
'GetWindow Constants
Public Const GW_CHILD = 5
Public Const GW_HWNDFIRST = 0
Public Const GW_HWNDLAST = 1
Public Const GW_HWNDNEXT = 2
Public Const GW_HWNDPREV = 3
Public Const GW_OWNER = 4
'   API Functions
Public Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Public Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Public Declare Function GetDesktopWindow Lib "user32" () As Long
Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long


Sub TestRoutine()
    Dim objShell As Object
    Dim oExec As Object
    Dim strResults As String

    Set objShell = CreateObject("WScript.Shell")
    Set oExec = objShell.Exec("CMD /K")
    Call HideWindow(oExec.ProcessID)

    With oExec
        .StdIn.WriteLine "Ping 127.0.0.1"
        .StdIn.WriteLine "ipconfig /all"
        .StdIn.WriteLine "exit"
        Do Until .StdOut.AtEndOfStream
            strResults = strResults & vbCrLf & .StdOut.ReadLine
            DoEvents
        Loop
    End With
    Set oExec = Nothing
    Debug.Print strResults
End Sub


Function HideWindow(iProcessID)
    Dim lngWinHwnd As Long
    Do
        lngWinHwnd = GetHwndFromProcess(CLng(iProcessID))
        DoEvents
    Loop While lngWinHwnd = 0
    HideWindow = ShowWindow(lngWinHwnd, SW_MINIMIZE)
End Function

Function GetHwndFromProcess(p_lngProcessId As Long) As Long
    Dim lngDesktop As Long
    Dim lngChild As Long
    Dim lngChildProcessID As Long
    On Error Resume Next
    lngDesktop = GetDesktopWindow()
    lngChild = GetWindow(lngDesktop, GW_CHILD)
    Do While lngChild <> 0
        Call GetWindowThreadProcessId(lngChild, lngChildProcessID)
        If lngChildProcessID = p_lngProcessId Then
            GetHwndFromProcess = lngChild
            Exit Do
        End If
        lngChild = GetWindow(lngChild, GW_HWNDNEXT)
    Loop
    On Error GoTo 0
End Function

显示窗口功能: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548%28v=vs.85%29.aspx

GetWindow 函数: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633515%28v=vs.85%29.aspx

GetDesktopWindow 函数: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633504%28v=vs.85%29.aspx

GetWindowThreadProcessId 函数: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633522%28v=vs.85%29.aspx

如果您需要有关 API 工作原理的更多信息,可以通过 google 快速搜索为您提供大量信息。

我希望这可以帮助...谢谢。

【讨论】:

    【解决方案2】:

    找到了一种非常可行且无声的方法:

    Dim strCommand as string
    Dim strPing As String
    
    strCommand = "%ComSpec% /C %SystemRoot%\system32\ping.exe -n 1 -w 500 " & myIP & " | " & "%SystemRoot%\system32\find.exe /i " & Chr(34) & "TTL=" & Chr(34)
    strPing = fShellRun(strCommand)
    
    If strPing = "" Then
        MsgBox "Not Connected"
    Else
        MsgBox "Connected!"
    End If
    
    '''''''''''''''''''''''''''
    
    Function fShellRun(sCommandStringToExecute)
    
    ' This function will accept a string as a DOS command to execute.
    ' It will then execute the command in a shell, and capture the output into a file.
    ' That file is then read in and its contents are returned as the value the function returns.
    
    ' "myIP" is a user-selected global variable
    
    Dim oShellObject, oFileSystemObject, sShellRndTmpFile
    Dim oShellOutputFileToRead, iErr
    
    Set oShellObject = CreateObject("Wscript.Shell")
    Set oFileSystemObject = CreateObject("Scripting.FileSystemObject")
    
        sShellRndTmpFile = oShellObject.ExpandEnvironmentStrings("%temp%") & oFileSystemObject.GetTempName
        On Error Resume Next
        oShellObject.Run sCommandStringToExecute & " > " & sShellRndTmpFile, 0, True
        iErr = Err.Number
    
        On Error GoTo 0
        If iErr <> 0 Then
            fShellRun = ""
            Exit Function
        End If
    
        On Error GoTo err_skip
        fShellRun = oFileSystemObject.OpenTextFile(sShellRndTmpFile, 1).ReadAll
        oFileSystemObject.DeleteFile sShellRndTmpFile, True
    
    Exit Function
    
    err_skip:
        fShellRun = ""
        oFileSystemObject.DeleteFile sShellRndTmpFile, True
    
    
    End Function
    

    【讨论】:

    • 这段代码对我有用,除了当我从 VBA 运行时,没有任何东西写入 sShellRndTmpFile(它甚至没有被创建)。但是,当我在命令行上运行 sCommandStringToExecute & " > " & sShellRndTmpFile 时,会创建 sShellRndTmpFile。知道为什么吗?
    【解决方案3】:

    wscript 的 run 方法已经包含要最小化运行的参数。因此,如果没有上面显示的所有努力,只需使用

    旧代码

    oShellObject.Run sCommandStringToExecute & " > " & sShellRndTmpFile, 0, True
    

    新代码

    oShellObject.Run sCommandStringToExecute & " > " & sShellRndTmpFile, 7, True
    

    有关在 wscript 中使用 run 方法的信息,请参阅 Microsoft 帮助。

    问候

    Ytracks

    【讨论】:

      猜你喜欢
      • 2017-12-16
      • 1970-01-01
      • 2011-04-19
      • 1970-01-01
      • 2014-05-29
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      相关资源
      最近更新 更多