找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 6620|回复: 9

【VB】VisualFTP:演示如何通过管道与控制台程序交互

[复制链接]
发表于 2015-2-11 17:17:04 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
这是个FTP工具。
这个程序写得很简单,功能并没有完全实现。源码演示如何通过STDIN和STDOUT控制一个程序。也就是相当于我给ftp.exe写了一个图形界面。
它的反应并不是很快,而且无法下载文件夹、无法上传文件夹、无法删除有内容的文件夹。只能对文件进行操作。
随时欢迎VB高手帮忙完善!
20150211171210.png
重要部分的代码:
  1. Attribute VB_Name = "FTPOperation"
  2. Option Explicit

  3. '安全属性
  4. Private Type SECURITY_ATTRIBUTES
  5.     nLength As Long
  6.     lpSecurityDescriptor As Long
  7.     bInheritHandle As Long
  8. End Type
  9. '启动信息
  10. Private Type STARTUPINFO
  11.     cb As Long
  12.     lpReserved As String
  13.     lpDesktop As String
  14.     lpTitle As String
  15.     dwX As Long
  16.     dwY As Long
  17.     dwXSize As Long
  18.     dwYSize As Long
  19.     dwXCountChars As Long
  20.     dwYCountChars As Long
  21.     dwFillAttribute As Long
  22.     dwFlags As Long
  23.     wShowWindow As Integer
  24.     cbReserved2 As Integer
  25.     lpReserved2 As Long
  26.     hStdInput As Long
  27.     hStdOutput As Long
  28.     hStdError As Long
  29. End Type
  30. '进程信息
  31. Private Type PROCESS_INFORMATION
  32.     hProcess As Long
  33.     hThread As Long
  34.     dwProcessId As Long
  35.     dwThreadId As Long
  36. End Type
  37. '重叠
  38. Private Type OVERLAPPED
  39.     Internal As Long
  40.     InternalHigh As Long
  41.     offset As Long
  42.     OffsetHigh As Long
  43.     hEvent As Long
  44. End Type

  45. '一些基本的API
  46. Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
  47. Private Declare Function GetLastError Lib "kernel32" () As Long
  48. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

  49. '启动信息属性
  50. Private Const STARTF_USESHOWWINDOW = &H1
  51. Private Const STARTF_USESTDHANDLES = &H100

  52. '启动窗口的属性
  53. Private Const SW_HIDE = 0

  54. '进程状态
  55. Private Const STATUS_PENDING = &H103&
  56. Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
  57. Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long

  58. '句柄控制
  59. Private Const DUPLICATE_SAME_ACCESS = &H2
  60. Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As Any) As Long
  61. Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, lpOverlapped As Any) As Long
  62. Private Declare Function PeekNamedPipe Lib "kernel32" (ByVal hNamedPipe As Long, lpBuffer As Any, ByVal nBufferSize As Long, lpBytesRead As Long, lpTotalBytesAvail As Long, lpBytesLeftThisMessage As Long) As Long
  63. Private Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As Any, lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long
  64. Private Declare Function CreatePipe Lib "kernel32" (phReadPipe As Long, phWritePipe As Long, lpPipeAttributes As SECURITY_ATTRIBUTES, ByVal nSize As Long) As Long
  65. Private Declare Function DuplicateHandle Lib "kernel32" (ByVal hSourceProcessHandle As Long, ByVal hSourceHandle As Long, ByVal hTargetProcessHandle As Long, lpTargetHandle As Long, ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwOptions As Long) As Long
  66. Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

  67. 'FTP进程信息
  68. Global FTPProcInfo As PROCESS_INFORMATION

  69. 'FTP.exe的StdIn的写句柄和StdOut的读句柄
  70. Global hChildIn As Long, hChildOut As Long

  71. '从FTP.exe的StdOut读取的字符串,和字符串大小
  72. Global StrBuf() As Byte, cbStrBuf As Long

  73. '主机、用户名、密码
  74. Global Host As String, Username As String, Password As String

  75. Global CurPath As String '当前操作的远程路径
  76. Global LastStatus As String, LastContactTime As Single '最后状态、最后交互时间
  77. Global LastFile As String '最后操作的文件
  78. Global Script As String, ScriptSetPW As Boolean '登录脚本文件地址、是否通过这个脚本输入账号密码

  79. '是不是错误地关闭了、操作后是否刷新
  80. Global CloseOnError As Boolean

  81. Type CmdType
  82.     Cmd As String
  83.     Stt As String
  84. End Type

  85. Global Commands() As CmdType, NbCommands As Long


  86. '启动FTP.exe进程,并对其进行控制
  87. Sub StartProc()
  88. Dim SecAttr As SECURITY_ATTRIBUTES

  89. '安全属性
  90. SecAttr.nLength = Len(SecAttr)
  91. SecAttr.bInheritHandle = True '承接句柄
  92. SecAttr.lpSecurityDescriptor = 0

  93. '创建StdIn的管道
  94. Dim StdInR As Long, StdInW As Long
  95. If CreatePipe(StdInR, StdInW, SecAttr, 0) = 0 Then
  96.     AddLog "StdIn pipe creation failed:" & GetLastError
  97. End If

  98. '创建StdOut的管道
  99. Dim StdOutR As Long, StdOutW As Long
  100. If CreatePipe(StdOutR, StdOutW, SecAttr, 0) = 0 Then
  101.     AddLog "StdOut pipe creation failed:" & GetLastError
  102. End If

  103. '启动信息
  104. Dim StartInfo As STARTUPINFO
  105. StartInfo.cb = Len(StartInfo)
  106. StartInfo.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW '修改管道和窗口方式
  107. StartInfo.wShowWindow = SW_HIDE '隐藏FTP.exe的窗口
  108. StartInfo.hStdInput = StdInR '改变其控制台管道
  109. StartInfo.hStdOutput = StdOutW
  110. StartInfo.hStdError = StdOutW

  111. hChildIn = StdInW '这是留给我们来操作的管道句柄
  112. hChildOut = StdOutR

  113. LastStatus = "START" '当前状态:启动
  114. LastContactTime = Timer '最后一次发送命令的时间。

  115. '用来登录的脚本。貌似WriteStr无法填写密码
  116. '因此采用这种方式登录
  117. Script = App.Path & "\script.txt"
  118. Open Script For Output As #1
  119. Print #1, Username '写入用户名
  120. Print #1, Password '写入密码
  121. Close #1
  122. ScriptSetPW = True

  123. '创建进程
  124. If CreateProcess(vbNullString, "ftp -v -s:" & Script & " " & Host, ByVal 0, ByVal 0, True, 0, ByVal 0, vbNullString, StartInfo, FTPProcInfo) = 0 Then
  125.     MsgBox "创建FTP进程失败。", vbCritical
  126. End If

  127. LastStatus = "OPEN"

  128. '关闭我们不需要的句柄
  129. CloseHandle StdInR
  130. CloseHandle StdOutW
  131. End Sub

  132. '结束FTP进程
  133. Sub EndProc()
  134. If hChildIn Then CloseHandle hChildIn
  135. If hChildOut Then CloseHandle hChildOut
  136. If FTPProcInfo.hProcess Then
  137.     AddLog "Task killed."
  138.     TerminateProcess FTPProcInfo.hProcess, 0 '结束进程
  139.     CloseHandle FTPProcInfo.hProcess
  140. End If
  141. If FTPProcInfo.hThread Then CloseHandle FTPProcInfo.hThread
  142. hChildIn = 0
  143. hChildOut = 0
  144. FTPProcInfo.hProcess = 0
  145. FTPProcInfo.hThread = 0
  146. LastStatus = ""
  147. If CloseOnError Then
  148.     MsgBox "连接已经中断。" '如果是出着错退出的,提示用户
  149.     If frmMain.Conn Then frmMain.cmdConnect_Click
  150. End If
  151. CloseOnError = False
  152. End Sub

  153. '发送命令
  154. Sub SendCommand(ByVal Cmd As String, ByVal Status As String)
  155. If LastStatus = "" Then CheckRun
  156. If NbCommands Then
  157.     ReDim Preserve Commands(NbCommands)
  158. Else
  159.     ReDim Commands(NbCommands)
  160. End If
  161. Commands(NbCommands).Cmd = Cmd
  162. Commands(NbCommands).Stt = Status
  163. NbCommands = NbCommands + 1
  164. End Sub

  165. '将下一个命令写入到FTP进程的StdIn管道
  166. Function WriteNextCommand() As Boolean
  167. If NbCommands Then
  168.     WriteNextCommand = WriteStr(hChildIn, Commands(0).Cmd)
  169.     LastStatus = Commands(0).Stt
  170.     NbCommands = NbCommands - 1
  171.    
  172.     If NbCommands Then
  173.         Dim I&
  174.         For I = 1 To NbCommands
  175.             Commands(I - 1) = Commands(I)
  176.         Next
  177.         ReDim Preserve Commands(NbCommands - 1)
  178.     Else
  179.         Erase Commands
  180.     End If
  181. End If
  182. End Function

  183. '写入字符串到FTP进程的StdIn管道
  184. Private Function WriteStr(ByVal Handle As Long, Str_ As String) As Boolean
  185. CheckRun

  186. Dim StrMB() As Byte, NbWrite As Long
  187. AddLog Str_
  188. StrMB = StrConv(Str_ & vbCrLf, vbFromUnicode)
  189. WriteStr = WriteFile(Handle, StrMB(0), UBound(StrMB) + 1, NbWrite, ByVal 0)
  190. LastContactTime = Timer
  191. End Function

  192. '检查是否已经运行FTP.exe,如果没有则启动它
  193. Sub CheckRun()
  194. Dim ExitCode As Long
  195. If FTPProcInfo.hProcess Then
  196.     If GetExitCodeProcess(FTPProcInfo.hProcess, ExitCode) Then
  197.         If ExitCode <> STATUS_PENDING Then StartProc
  198.     Else
  199.         StartProc
  200.     End If
  201. Else
  202.     StartProc
  203. End If
  204. End Sub

  205. '打开FTP服务器。
  206. Sub OpenFTP()
  207. '不知道为毛非得先写一个回车到StdIn才能启动进程
  208. WriteStr hChildIn, vbCrLf
  209. SendCommand "binary", "SETBIN"
  210. SendCommand "quote pasv", "SETPASV"
  211. DirList
  212. End Sub

  213. '取得当前目录
  214. Sub GetCurDir()
  215. SendCommand "pwd", "GETCUR"
  216. End Sub

  217. '显示目录
  218. Sub DirList()
  219. SendCommand "dir", "DIR"
  220. End Sub

  221. '切换文件夹
  222. Sub ChangeDir(ByVal Target As String)
  223. SendCommand "cd " & Target, "CD"
  224. End Sub

  225. '创建文件夹
  226. Sub MakeDir(ByVal DirName As String)
  227. SendCommand "mkdir " & DirName, "MKDIR"
  228. End Sub

  229. '移除文件夹
  230. Sub RemoveDir(ByVal DirName As String)
  231. SendCommand "rmdir " & DirName, "RMDIR"
  232. End Sub

  233. '上传文件
  234. Sub PutFile(ByVal LocalPath As String, ByVal RemotePath As String)
  235. SendCommand "put " & LocalPath & " " & RemotePath, "PUT"
  236. End Sub

  237. '下载文件
  238. Sub GetFile(ByVal RemotePath As String, ByVal LocalPath As String)
  239. SendCommand "get " & RemotePath & " " & LocalPath, "GET"
  240. End Sub

  241. '移除文件
  242. Sub DelFile(ByVal FilePath As String)
  243. SendCommand "del " & FilePath, "DEL"
  244. End Sub

  245. '关闭连接
  246. Sub CloseFTP(ByVal OnError As Boolean)
  247. CloseOnError = OnError
  248. LastStatus = "CLOSE"
  249. WriteStr hChildIn, "close"
  250. Erase Commands
  251. NbCommands = 0
  252. End Sub

  253. '清空文件夹
  254. Sub ClearDir()
  255. Dim I&
  256. For I = 0 To NbFList - 1
  257.     If FList(I).IsDir = False And FList(I).IsLink = False Then DelFile FList(I).FileName
  258. Next
  259. End Sub

  260. '检查FTP.exe对StdOut的输出,然后将内容读取到StrBuf
  261. Function CheckToBuf(ByVal Handle As Long) As String
  262. Dim NbTobeRead As Long, NbGot As Long
  263. PeekNamedPipe Handle, ByVal 0, 0, 0, NbTobeRead, ByVal 0
  264. If NbTobeRead Then
  265.     If cbStrBuf Then
  266.         ReDim Preserve StrBuf(cbStrBuf + NbTobeRead - 1)
  267.     Else
  268.         ReDim StrBuf(NbTobeRead - 1)
  269.     End If
  270.     ReadFile Handle, StrBuf(cbStrBuf), NbTobeRead, NbGot, ByVal 0
  271.     cbStrBuf = cbStrBuf + NbTobeRead
  272. End If
  273. CheckBuf
  274. End Function

  275. '检查StrBuf,如果它包含了一个完整的行,则将其取出并分析。
  276. Sub CheckBuf()
  277. Dim I&, J&, K&, S$
  278. If cbStrBuf Then
  279.     I = GetLfFromMB(StrBuf)
  280.     If I Then
  281.         Dim SingleLine() As Byte
  282.         ReDim SingleLine(I)
  283.         CopyMemory SingleLine(0), StrBuf(0), I + 1
  284.         For J = I + 1 To cbStrBuf - 1
  285.             StrBuf(K) = StrBuf(J)
  286.             K = K + 1
  287.         Next
  288.         cbStrBuf = K
  289.         If cbStrBuf Then
  290.             ReDim Preserve StrBuf(cbStrBuf - 1)
  291.         Else
  292.             Erase StrBuf
  293.         End If
  294.         S = StrConv(SingleLine, vbUnicode)
  295.         S = Left$(S, Len(S) - 2)
  296.         If Right$(S, 1) = vbCr Then S = Left$(S, Len(S) - 1)
  297.         ProcLine S
  298.     End If
  299. End If
  300. If LastStatus = "OK" Or LastStatus = "FAILED" Then '如果有空
  301.     WriteNextCommand '写入下一条命令
  302. End If
  303. If LastStatus <> "OK" And LastStatus <> "PUTTING" And LastStatus <> "GETTING" And Timer - LastContactTime >= 3 Then '三秒超时
  304.     AddLog "No response."
  305.     CloseOnError = True
  306.     EndProc
  307. End If
  308. If LastStatus = "CLOSED" Then
  309.     If frmMain.Conn Then frmMain.cmdConnect_Click
  310.     EndProc
  311. End If
  312. End Sub

  313. '处理一行消息。
  314. Sub ProcLine(LineStr As String)
  315. On Error Resume Next
  316. AddLog LineStr
  317. LastContactTime = Timer
  318. If CLng(Val(LineStr)) = 421 Then '如果已经超时
  319.     EndProc
  320.     OpenFTP
  321.     Exit Sub
  322. End If
  323. If Len(LineStr) = 0 Then Exit Sub
  324. Debug.Print LastStatus, LineStr
  325. Select Case LastStatus
  326.     Case ""  '无状态
  327.         '什么也不做
  328.     Case "OPEN" '打开服务器
  329.         If InStr(LineStr, "220") Then '显示欢迎信息
  330.             LastStatus = "LOGIN1" '输入用户名状态
  331.             If Not ScriptSetPW Then WriteStr hChildIn, Username & vbCrLf
  332.         ElseIf InStr(LineStr, "250") Then
  333.             '消息
  334.         Else
  335.             LastStatus = "UNKNOWN"
  336.         End If
  337.     Case "LOGIN1" '输入用户名后
  338.         If InStr(LineStr, "220") Then
  339.             '仍然在显示欢迎信息
  340.         ElseIf InStr(LineStr, "331") Then '输入密码的状态
  341.             If Not ScriptSetPW Then WriteStr hChildIn, Password & vbCrLf
  342.             LastStatus = "LOGIN2"
  343.         ElseIf InStr(LineStr, "250") Then
  344.             '消息
  345.         Else
  346.             LastStatus = "UNKNOWN"
  347.         End If
  348.     Case "LOGIN2" '输入密码后
  349.         If InStr(LineStr, "230") Then '登录成功
  350.             LastStatus = "OK"
  351.             Kill Script '删除登录脚本文件,以免泄露用户名密码,虽说本程序本来就不安全
  352.             ScriptSetPW = False
  353.         ElseIf InStr(LineStr, "250") Then
  354.             '消息
  355.         Else
  356.             LastStatus = "UNKNOWN"
  357.         End If
  358.     Case "SETBIN" '设置二进制传输
  359.         If InStr(LineStr, "200") Then '命令成功
  360.             LastStatus = "OK"
  361.         ElseIf InStr(LineStr, "250") Then
  362.             '消息
  363.         Else
  364.             LastStatus = "UNKNOWN"
  365.         End If
  366.     Case "SETPASV" '设置被动模式
  367.         If InStr(LineStr, "227") Then '命令成功
  368.             LastStatus = "OK"
  369.         Else
  370.             LastStatus = "UNKNOWN"
  371.         End If
  372.     Case "GETCUR" '取得当前路径
  373.         If InStr(LineStr, "257") Then '命令成功
  374.             CurPath = GetQuote(LineStr)
  375.             frmMain.txtCurDir.Text = CurPath '显示到主窗体
  376.             LastStatus = "OK"
  377.         ElseIf InStr(LineStr, "250") Then
  378.             '消息
  379.         Else
  380.             LastStatus = "UNKNOWN"
  381.         End If
  382.     Case "CD" '切换目录
  383.         If InStr(LineStr, "250") Then
  384.             LastStatus = "OK"
  385.         ElseIf InStr(LineStr, "550") Then
  386.             LastStatus = "FAILED" '切换目录失败
  387.         Else
  388.             LastStatus = "UNKNOWN"
  389.         End If
  390.     Case "MKDIR" '创建文件夹
  391.         If InStr(LineStr, "257") Then
  392.             LastStatus = "OK"
  393.         ElseIf InStr(LineStr, "550") Then
  394.             LastStatus = "FAILED" '创建文件夹失败
  395.         ElseIf InStr(LineStr, "250") Then
  396.             '消息
  397.         Else
  398.             LastStatus = "UNKNOWN"
  399.         End If
  400.     Case "RMDIR" '移除文件夹
  401.         If InStr(LineStr, "250") Then
  402.             LastStatus = "OK"
  403.         ElseIf InStr(LineStr, "550") Then
  404.             LastStatus = "FAILED" '删除文件夹失败
  405.         Else
  406.             LastStatus = "UNKNOWN"
  407.         End If
  408.     Case "DEL" '删除文件
  409.         If InStr(LineStr, "250") Then
  410.             LastStatus = "OK"
  411.         ElseIf InStr(LineStr, "550") Then
  412.             LastStatus = "FAILED" '删除文件失败
  413.         Else
  414.             LastStatus = "UNKNOWN"
  415.         End If
  416.     Case "PUT" '上传文件
  417.         If InStr(LineStr, "200") Then
  418.             'PORT命令成功
  419.         ElseIf InStr(LineStr, "150") Then
  420.             '开始传送
  421.             LastStatus = "PUTTING"
  422.         ElseIf InStr(LineStr, "550") Then '上传失败
  423.             LastStatus = "FAILED"
  424.         ElseIf InStr(LineStr, "250") Then
  425.             '消息
  426.         Else
  427.             LastStatus = "UNKNOWN"
  428.         End If
  429.     Case "PUTTING" '正在上传文件
  430.         If InStr(LineStr, "226") Then
  431.             '上传成功
  432.             LastStatus = "OK"
  433.         ElseIf InStr(LineStr, "250") Then
  434.             '消息
  435.         ElseIf InStr(LineStr, "550") Then '上传失败
  436.             LastStatus = "FAILED"
  437.         Else
  438.             LastStatus = "UNKNOWN"
  439.         End If
  440.     Case "GET" '下载文件
  441.         If InStr(LineStr, "200") Then
  442.             'PORT命令成功
  443.         ElseIf InStr(LineStr, "150") Then
  444.             '开始传送
  445.             LastStatus = "GETTING"
  446.         ElseIf InStr(LineStr, "550") Then '下载失败
  447.             LastStatus = "FAILED"
  448.         ElseIf InStr(LineStr, "250") Then
  449.             '消息
  450.         Else
  451.             LastStatus = "UNKNOWN"
  452.         End If
  453.     Case "GETTING" '正在下载文件
  454.         If InStr(LineStr, "226") Then
  455.             '上传成功
  456.             LastStatus = "OK"
  457.         ElseIf InStr(LineStr, "250") Then
  458.             '消息
  459.         ElseIf InStr(LineStr, "550") Then '下载失败
  460.             LastStatus = "FAILED"
  461.         Else
  462.             LastStatus = "UNKNOWN"
  463.         End If
  464.     Case "DIR" '列出目录
  465.         If InStr(LineStr, "200") Then
  466.             'PORT命令成功
  467.         ElseIf InStr(LineStr, "250") Then
  468.             '消息
  469.         ElseIf InStr(LineStr, "150") Then '传输目录成功
  470.             LastStatus = "DIROK"
  471.             ClearFileList
  472.         Else
  473.             LastStatus = "UNKNOWN"
  474.         End If
  475.     Case "DIROK" '传输目录成功
  476.         'If LineStr Like "?????????? * * * * * * ??:?? *" Then '如果看起来是目录格式
  477.         If InStr(LineStr, "226") Then '命令成功
  478.             LastStatus = "OK"
  479.         ElseIf InStr(LineStr, "250") Then
  480.             '消息
  481.         Else
  482.             ParseFListString LineStr
  483.             frmMain.UpdateFileList
  484.         End If
  485.     Case "CLOSE" '关闭连接
  486.         If InStr(LineStr, "221") Then '关闭成功
  487.             LastStatus = "CLOSED"
  488.         ElseIf InStr(LineStr, "250") Then
  489.             '消息
  490.         Else
  491.             LastStatus = "CLOSED"
  492.         End If
  493. End Select
  494. End Sub
复制代码
这个程序因为是临时作品,我并没有给它写好注释,还请大家见谅。
BIN: VisualFTP.7z (22.21 KB, 下载次数: 9)
SRC: VisualFTP_Src.7z (33.99 KB, 下载次数: 12, 售价: 10 个宅币)

本帖被以下淘专辑推荐:

回复

使用道具 举报

 楼主| 发表于 2015-2-11 17:17:53 | 显示全部楼层
我觉得它的亮点其实是左边和右边那个文件列表视图。那是用PictureBox画的。
回复 赞! 靠!

使用道具 举报

发表于 2015-2-11 17:37:52 | 显示全部楼层
嗯  我调用CMD.EXE做的"远程终端"就是这么做的
回复 赞! 靠!

使用道具 举报

发表于 2015-2-11 18:50:27 | 显示全部楼层
不错,不过我更喜欢目录树形式的
回复 赞! 靠!

使用道具 举报

发表于 2015-5-30 11:48:33 | 显示全部楼层
请问怎么向管道发送crtl+z?
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2015-5-30 15:31:45 | 显示全部楼层
FFFFFFFE 发表于 2015-5-30 11:48
请问怎么向管道发送crtl+z?

你先写个控制台程序判断Ctrl+Z是什么值,然后再用我这个源码发送那个值就行了。
回复 赞! 靠!

使用道具 举报

发表于 2017-11-13 19:41:25 | 显示全部楼层
过来学习下
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2018-5-6 00:58:32 | 显示全部楼层
下次我再写管道交互的话我不会再用这种一问一答方式了。
回复 赞! 靠!

使用道具 举报

发表于 2018-5-6 07:08:02 | 显示全部楼层
这 个很不错.可以借鉴给控制台程序写界面
回复 赞! 靠!

使用道具 举报

发表于 2022-5-9 16:12:40 | 显示全部楼层

论坛有你真的精彩~
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-12-26 00:38 , Processed in 0.042204 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表