2014-01-08 6 views
1

У меня есть таблица, которая суммирует использование сервера. Электронная таблица ссылается на текстовый файл, который обновляется, когда VBA посылает некоторые команды на сервер Linux через командную строку Windows (и Cygwin). Моя проблема в том, что единственный способ, которым я нашел выполнение команд в Cygwin, - это выполнить команду SendKeys. Это приводит к двум проблемам:VBA SendKeys к определенному окну

  1. Я должен доверять, что пользователь не будет нажимать где-нибудь, пока скрипт не будет запущен.
  2. Мне нужно скопировать количество времени, чтобы ждать выполнения команды до следующей команды.

Я бы (и сделал) попытался создать файл bash для запуска в Cygwin, но я не знаю, как это сделать, что также позволяет пользователю вводить свой пароль для входа на сервер Linux. В настоящее время я получаю пароль пользователя из UserForm, который выполняется до того, как будет выполнен основной код. Затем этот пароль сохраняется на «очень скрытом» листе, который удаляется при закрытии приложения.

настоящее время я использую следующий скрипт для запуска команды:

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 Program Settings' – 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: «Требуется объект», но основная часть команд по-прежнему выполняется правильно, поэтому я просто игнорирую ошибку. Я также понял, как выполнить свою команду в одной строке, поэтому мне не нужно беспокоиться о команде stdIn.Write, которая раньше не работала. Я мог бы использовать команду Shell(), но мне нужно убедиться, что команда завершила выполнение (с помощью опции bWaitOnReturn), чтобы убедиться, что у меня есть самый свежий файл при запуске скрипта обновления. Сказав это, я считаю, что, поскольку у меня Linux выписывает вывод команды в файл, файл не закончил обновление, когда VBA говорит, что команда завершила выполнение. Тем не менее, я считаю, что я понял, что нужно проверить, что последняя строка текста отформатирована правильно в файле (так как это должна быть дата), поэтому это не должно быть проблемой.

+0

Удаление моего ответа, потому что «мой ответ не совсем правильный» :-) И этот ответ все равно решает вашу проблему. – anishsane

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