2014-01-08 51 views
1

我有一個電子表格,總結了服務器的使用情況。電子表格引用了一個文本文件,當我使用VBA通過Windows命令提示符(和Cygwin)向Linux服務器發送一些命令時,該文本文件會被更新。我的問題是,我發現在Cygwin中執行命令的唯一方法是通過SendKeys命令。這導致了兩個問題:VBA SendKeys到特定窗口

  1. 我必須相信用戶不會在某個地方點擊,直到腳本運行完畢。
  2. 我必須硬編碼等待命令執行的時間量才能發送下一個命令。

我會(並且)嘗試創建一個在Cygwin中運行的bash文件,但我不知道如何做到這一點,也允許用戶輸入他們的密碼登錄到Linux服務器。我目前從執行主代碼之前運行的用戶窗體獲取用戶密碼。這個密碼然後被保存到一個「非常隱藏」的工作表中,當應用程序關閉時它將被刪除。

我目前使用下面的腳本來運行這些命令:

Public Sub test() 
    ' Declare Variables 
    Dim cmd As String 
    Dim ret As Double 
    Dim LastRow As Integer 
    Dim PssWrd As String 

    PssWrd = Worksheets("PssWrd").Range("A1").Value 

    ' Run Linux Commands 
    cmd = "C:\cygwin\Cygwin.bat" 
    ret = Shell(cmd, vbMinimizedFocus) 
    wait 0.02 
    cmd = "ssh " & Worksheets("Settings").Range("LOGIN") & "~" ' Format: [email protected] 
    SendKeys cmd 
    cmd = PssWrd & "~" 
    SendKeys cmd 
    wait 2.78 
    cmd = "{(} date ; fs ; qstat ; date {)} > & zout &~" 
    SendKeys cmd 
    cmd = "exit~" 
    SendKeys cmd 
    wait 0.5 
    cmd = "exit~" 
    SendKeys cmd 
    wait 5 
    ' Update PivotTable and other data 
End Sub 
Public Sub wait(PauseTime As Double) 
    Dim Start As Double 
    Dim Finish As Double 
    Dim TotalTime As Double 
    Start = Timer ' Set start time 
    Do While Timer < Start + PauseTime 
     DoEvents ' Yield to other processes 
    Loop 
    Finish = Timer ' Set end time 
    TotalTime = Finish - Start ' Calculate total time 
End Sub 

有沒有什麼辦法擊鍵至少發送到特定的窗口,而不是僅僅在活動窗口?任何幫助將不勝感激,任何額外的必要信息將隨時提供。

+0

而不是一個「非常隱藏的」工作表,您可能需要考慮使用'SaveSetting' /'GetSetting(...)'在用戶的註冊表中存儲/檢索用戶憑證' – MikeD

+0

'SaveSetting' /'GetSetting'也不安全...獲取存儲在'HKEY_CURRENT_USER \ Software \ VB和VBA程序設置' – anishsane

+0

我可以讓用戶在每次運行腳本時輸入他的密碼,但是我想讓他更容易使用。這個腳本最常見的用途是將某個副本保存到本地計算機並運行它來檢查我們公司服務器上的活動。當文件關閉時,該表會被刪除,所以他們從網絡獲取的版本不會保存任何人的密碼。而且,即使他們很難找出代碼的工作原理並使工作表可見,他們也只能看到他們自己的。 – tlewis3348

回答

1

好吧。我想我找到了解決方案。感謝所有幫助(@anishsane)指引我朝着正確的方向發展!這裏是我更新的代碼:

Public Sub test() 
    ' Declare Variables 
    Dim cmd As String 
    Dim ret As Double 
    Dim LastRow As Integer 
    Dim PssWrd As String 
    Dim WshShell As Object 
    Dim plink_object As Object 

    PssWrd = Worksheets("PssWrd").Range("A1").Value 

    ' Run Linux Commands 
    Set WshShell = CreateObject("WScript.Shell") 
    On Error Resume Next 
    Set plink_object = WshShell.Run("""C:\Program Files (x86)\PuTTY\plink.exe"" -ssh " & Worksheets("Settings").Range("LOGIN") & " -pw " & PssWrd & " ""(date; fs; qstat; date) > &zout&""", 7, True) 
    On Error GoTo 0 
    ' Update PivotTable and other data 
End Sub 

很明顯,在VBA中不需要WScript。此外,wshshell.exec似乎在某些時候失敗,因爲命令永遠不會被執行(儘管啓動PuTTY/Plink)。出於某種原因,WshShell.Run命令導致「運行時錯誤'424':Object required'錯誤,但命令的基本部分仍然正確執行,所以我只是將錯誤忽略。我也想出瞭如何在一行中執行我的命令,所以我不必擔心之前不工作的stdIn.Write命令。我可以使用Shell()命令,但我需要確保該命令已完成執行(通過bWaitOnReturn選項),以確保在更新腳本運行時具有最新的文件。話雖如此,我相信由於我正在使用Linux將命令的輸出寫出到一個文件中,所以當VBA表示命令執行完成時,文件還沒有完成更新。不過,我相信我已經想出了一種方法來檢查文件的最後一行是否在文件中正確格式化(因爲它應該是日期),所以這應該不成問題。

+0

刪除我的答案,因爲「我的回答不完全正確」:-)&這個答案無論如何解決您的問題。 – anishsane