前提:使用 VBA (Access),运行 ftp 并使用 CreateProcess 和 Read/WriteFile 将命令传递给它。
Objective: 使用管道写入 ftp 进程 stdIn 以发送命令并读取 stdOut 以确定来自 ftp 目录结构的信息。此外,要了解在使用 Windows API 函数时格式化我的代码的正确方法,并确定另一种方法(使用 API 控制台命令)是否更合适。
我试过的:以下代码挂在 ReadFile 或 WriteFile 调用中。我不确定我应该使用同步还是异步以及将我发送的命令放在哪里。如参考文献 [2] 中所述,我将 ReadFile 调用置于等待循环中。
Public Sub ExecCmd(cmdline As String)
Dim proc As PROCESS_INFORMATION
Dim start As STARTUPINFO
Dim hReadPipe1 As Long, hReadPipe2 As Long
Dim hWritePipe1 As Long, hWritePipe2 As Long
Dim ret As Integer, buff As String, lngBytes As Long
Dim lpCurrentDirectory As String
'Create pipes for reading/writing to console
If CreatePipe(hReadPipe1, hWritePipe1, vbNull, 0&) = 0 Then _
MsgBox "createpipe failed" 'Stdout
If CreatePipe(hReadPipe2, hWritePipe2, vbNull, 0&) = 0 Then _
MsgBox "createpipe failed" 'Stdin
' Initialize structures etc
start.cb = Len(start)
start.lpTitle = "CBase Console"
start.wShowWindow = 0
start.hStdOutput = hWritePipe1
start.hStdError = hWritePipe1
start.hStdInput = hReadPipe2
lpCurrentDirectory = "H:\"
buff = Space(260)
If CreateProcess(0&, cmdline, 0&, 0&, 1&, NORMAL_PRIORITY_CLASS, 0&, _
lpCurrentDirectory, start, proc) = 0 Then _
MsgBox "createprocess failed"
buff = "echo hello world" & vbCrLf
ret = WriteFile(hWritePipe2, buff, Len(buff), lngBytes, vbNull) 'code hangs here
Do 'or code hangs on readfile if writefile is removed
If ReadFile(hReadPipe1, buff, Len(buff), lngBytes, vbNull) = 0 Then _
MsgBox "readfile failed"
ret = WaitForSingleObject(proc.hProcess, 0)
DoEvents
Loop Until ret <> 258
ret = CloseHandle(proc.hProcess)
ret = CloseHandle(proc.hThread)
ret = CloseHandle(hReadPipe1)
ret = CloseHandle(hWritePipe2)
End Sub
相关文章(由于无法转换代码格式,无法从中获得答案):
[1]:使用 CreateProcess 函数启动时,cmd.exe 在某些情况下不会终止
[2]:Win32 ReadFile 挂起时
从管道
[3]读取: win32 (WinAPI) 中的管道损坏