2013-10-03 6 views
0

Я выполняю быстрый PING по выбранному пользователем IP-адресу сервера, чтобы подтвердить, что он доступен.Команда WScript - Run Minimized? (MSAccess/VBA)

Следующий код выполняет именно то, что мне нужно, за исключением того, что я хотел бы избежать быстрой вспышки окна командной оболочки.

Что мне нужно изменить, чтобы свести к минимуму это досадное окно 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 
+0

возможно дубликат [Хочу, чтобы скрыть окно командной строки при помощи метода WshShell.Exec] (http://stackoverflow.com/questions/15128517/want-to-hide-command -prompt-window-in-use-wshshell-exec-method) –

+0

Увидел этот метод, но у него нет роскоши для перенаправления на файл - несколько пользователей. Надеялся, чтобы поддерживать принцип stdout. Будет продолжать искать thx –

+1

Re: «не имеет роскоши для перенаправления на файл - несколько пользователей» - это то, что будет выполнено из front-end базы данных, и вы *** ***, убедившись, что каждый пользователь имеет их собственная локальная копия интерфейса, правильно ...? –

ответ

1

Найденный очень работоспособный и бесшумный подход:

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 
+0

Этот код работает для меня, за исключением того, что когда я запускаю из VBA, ничего не записывается в sShellRndTmpFile (он даже не создан). Однако при запуске sCommandStringToExecute & ">" & sShellRndTmpFile в командной строке создается sShellRndTmpFile. Любая идея почему? – Ivan

2

Этот вопрос может быть немного старый, но я полагаю, что этот ответ может все еще быть в состоянии помочь. (Испытано с Excel VBA, не был в состоянии проверить с Access)

WshShell.Exec Метод позволяет использовать .StdIn, .StdOut и функции .StdErr писать и читать из окна CONSOL. Метод WshShell.Run не позволяет использовать эту функцию, поэтому для некоторых целей используется Exec.

Несмотря на то, что нет встроенной функции для запуска метода Exec, сведенного к минимуму или скрытого, вы можете использовать API, чтобы быстро найти окно Exec hwnd и минимизировать/скрыть его.

Мой нижеприведенный скрипт берет ProcessID из объекта Exec, чтобы найти Hwnd окна. С помощью Hwnd вы можете установить состояние отображения окна.

Из моего тестирования с помощью Excel 2007 VBA, в большинстве случаев я даже не вижу окна ... В некоторых случаях он может отображаться в течение нескольких миллисекунд, но будет появляться только быстрое мерцание или мигать ... Примечание: I имел лучшие результаты с использованием SW_MINIMIZE, чем с SW_HIDE, но вы можете поиграть с ним.

Я добавил TestRoutine Sub, чтобы показать пример использования функции HideWindow. Функция 'HideWindow' использует функцию GetHwndFromProcess для получения окна hwnd из ProcessID.

Поместите ниже в модуль ...

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 

ShowWindow Функция: 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

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

Если вам нужна дополнительная информация о работе API, быстрый поиск в Google предоставит вам массу информации.

Я надеюсь, что это может помочь ... Спасибо.

1

Метод запуска wscript уже содержит argumewnts для запуска с минимальными значениями.Таким образом, не все, что усилие было показано выше, просто использовать

старый код

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

новый код

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

см Microsoft справку по использованию метода запуска в WScript.

рассматривает

Ytracks

Смежные вопросы