You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Excel VBA调用PLink实现SSH/Telnet:解决单命令登录延迟或维持会话执行多查询问题

Excel VBA调用PLink实现SSH/Telnet:解决单命令登录延迟或维持会话执行多查询问题

我太懂你这种痛苦了——每次跑命令都要重新建立SSH连接,光握手、验证就占了4秒,成千上万次下来不仅耗时惊人,还把电脑卡得没法用。下面针对你的问题逐一给出解决方案:

一、用PLink解决延迟问题:必须复用会话!

完全可以避免这个延迟!你当前的核心问题是每次执行命令都新建一个SSH连接,登录、密钥验证这些固定开销占了绝大多数时间。只要复用同一个SSH会话,后续命令的执行速度会快到几乎可以忽略。

二、维持会话批量执行命令的具体实现

这里给你两种可行的方法,第一种是基于你现有代码的轻量化修改,第二种是进阶方案:

方法1:用WshShell交互模式维持PLink会话

这种方式不需要额外依赖,直接用你已经在使用的Windows Script Host对象就能实现。核心思路是:

  • 先启动一个PLink交互进程(不附加命令参数,让它进入远程SSH shell)
  • 通过StdIn发送命令,通过StdOut读取输出
  • 识别远程主机的提示符(比如user@linuxbox:~$)来判断命令是否执行完成

修改后的VBA代码示例

首先在模块顶部声明全局变量,避免会话进程被意外销毁:

Option Explicit

Private oShell As WshShell
Private oExec As WshExec
Private strPrompt As String ' 远程主机的命令提示符,比如 "user@yourbox:~$ "

' 初始化SSH会话(只需要执行一次)
Sub InitSSHConnection()
    Dim plinkPath As String
    Dim sshUser As String
    Dim sshHost As String
    Dim sshPassword As String
    
    ' 替换成你的实际参数
    plinkPath = "C:\Tools\plink.exe" ' PLink的安装路径
    sshUser = "your_username"
    sshHost = "10.10.10.10"
    sshPassword = "your_password"
    strPrompt = sshUser & "@yourbox:~$ " ' 登录后看到的命令行提示符
    
    ' 启动PLink交互会话(不要加命令参数,进入远程shell)
    Dim cmd As String
    cmd = """" & plinkPath & """ -ssh " & sshUser & "@" & sshHost & " -pw " & sshPassword
    
    Set oShell = New WshShell
    Set oExec = oShell.Exec(cmd)
    
    ' 等待会话建立,跳过登录输出直到出现提示符
    Dim output As String
    Do While InStr(output, strPrompt) = 0
        Do While oExec.StdOut.AtEndOfStream = False
            output = output & oExec.StdOut.ReadAll
        Loop
        DoEvents ' 避免Excel假死,让电脑可以正常操作
    Loop
    
    Debug.Print "SSH会话已成功建立!"
End Sub

' 发送单个命令并返回清理后的结果
Function SendSSHCommand(strCmd As String) As String
    If oExec Is Nothing Then
        MsgBox "请先运行InitSSHConnection初始化会话!", vbExclamation
        Exit Function
    End If
    
    ' 发送命令(加换行符模拟回车键)
    oExec.StdIn.WriteLine strCmd
    
    ' 读取输出直到再次出现提示符(说明命令执行完成)
    Dim output As String
    output = ""
    Do While InStr(output, strPrompt) = 0
        Do While oExec.StdOut.AtEndOfStream = False
            output = output & oExec.StdOut.ReadAll
        Loop
        DoEvents
    Loop
    
    ' 清理输出:去掉命令本身、提示符和多余换行
    SendSSHCommand = CleanRawOutput(output, strCmd)
End Function

' 辅助函数:提取纯命令结果
Private Function CleanRawOutput(rawOutput As String, sentCmd As String) As String
    Dim startPos As Long, endPos As Long
    
    ' 跳过发送的命令行
    startPos = InStr(rawOutput, sentCmd) + Len(sentCmd) + 2 ' +2跳过命令后的换行
    
    ' 找到提示符位置,截断结果
    endPos = InStr(rawOutput, strPrompt) - 1
    
    ' 提取并去除前后空白
    CleanRawOutput = Trim(Mid(rawOutput, startPos, endPos - startPos))
End Function

' 关闭SSH会话
Sub CloseSSHConnection()
    If Not oExec Is Nothing Then
        oExec.StdIn.WriteLine "exit" ' 发送退出命令
        oExec.Terminate ' 强制终止进程
        Set oExec = Nothing
    End If
    Set oShell = Nothing
    Debug.Print "SSH会话已关闭!"
End Sub

' 测试批量命令执行
Sub BatchTestCommands()
    ' 初始化会话(只运行一次)
    InitSSHConnection
    
    ' 批量执行你的测试命令
    Dim testCmds(1 To 5) As String
    testCmds(1) = "databaseread -t Tag1.Value"
    testCmds(2) = "databaseread -t Tag2.Value"
    testCmds(3) = "databaseread -t Tag3.Value"
    testCmds(4) = "databaseread -t Tag4.Value"
    testCmds(5) = "databaseread -t Tag5.Value"
    
    Dim i As Integer
    For i = 1 To UBound(testCmds)
        Debug.Print "正在执行:" & testCmds(i)
        Debug.Print "结果:" & SendSSHCommand(testCmds(i))
        Debug.Print "------------------------"
    Next i
    
    ' 执行完毕关闭会话
    CloseSSHConnection
End Sub

关键注意事项:

  1. 一定要替换代码中的路径、账号、主机地址和提示符为你的实际信息
  2. 第一次运行前,建议手动用PLink连接一次目标主机,接受主机密钥(避免会话卡在密钥确认步骤);或者提前执行一次plink.exe -ssh user@10.10.10.10 -batch -pw password exit,自动保存密钥
  3. DoEvents的作用是让Excel在等待输出时不会假死,保证你可以正常操作电脑

方法2:PLink本地端口转发(进阶)

如果交互模式的输出处理太繁琐,你可以用PLink建立本地端口转发,把远程SSH会话映射到本地端口,然后用VBA的Socket控件(比如MSCOMCTL.Socket)连接本地端口发送命令。不过这种方式需要一定的网络编程基础,适合对稳定性要求更高的场景。

三、其他可选方案

如果PLink的方式还是不够灵活,你可以考虑这些替代方案:

  • PowerShell SSH模块:Windows 10+自带OpenSSH客户端,PowerShell可以用New-SSHSession建立持久会话,VBA调用PowerShell脚本传递命令并获取结果,无需依赖PLink
  • 第三方SSH控件:比如Chilkat SSH控件,提供原生VBA接口,直接在代码中建立会话、发送命令,稳定性更好但属于付费软件(有免费试用版)
  • Excel Power Query:如果你的查询可以结构化,Power Query支持通过SSH连接Linux主机,批量执行命令并将结果导入Excel,无需编写VBA

最后总结

对你的场景来说,方法1的PLink交互会话复用是最直接的解决方案,基于你现有代码修改即可,能把单命令执行时间从4秒压缩到毫秒级,同时避免电脑假死。

备注:内容来源于stack exchange,提问作者Scott

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 09:04:36