VB程序向CMD返回信息

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VB程序向CMD返回信息相关的知识,希望对你有一定的参考价值。

小弟写的VB程序可以用CMD向它输入参数
如:运行>cmd>c:\xx.exe 123
xx.exe程序就能获得数据123
但是像ping.exe这样的程序
运行>cmd>ping xxx.xxx.xxx.xxx后可以返回结果到CMD中
我想让我的程序也返回信息到CMD中,应该怎么做呢?

主要就是想知道程序怎样向调用他的CMD返回信息
底楼的朋友和我问题很接近了 但我的目的你们好象还没弄明白
我是这样想的:比如我的程序名称叫xx.exe放在C盘跟目录下
我打开CMD输入:c:\xx.exe xx
然后xx.exe就获得了参数xx他根据参数xx做一些事,然后把结果再返回到CMD中,就像ping.exe一样可以把网速等信息返回到CMD中
希望大家能明白我的意思

只有执着才能找到答案,在这里我先谢谢大家的帮助,但是你们的答案我不是很满意,希望理解

***我没有转移话题啊……只是新加了一些东西。请看【】中最后一句,只要把我原来的回答里aaa的内容改成【】里的即可。***
【最新修改:所有在CMD下执行的程序所返回的信息,都会自动返回到CMD里,比方说ping.exe,这个程序本身就是CMD下的程序,只能在CMD环境里执行,所以他执行后返回信息当然会返回到CMD里。因此,你只要在CMD里执行想要执行的程序(前提是这个程序可以在CMD下执行),程序的一切返回信息都会显示在CMD里。所以下面的代码部分只要把字符串变量“aaa”改为:
"cmd" & " " & "ping" & " " & "192.168.0.1"
即可。下同】
'先定义一个字符串变量:
dim aaa as string
'aaa就是你要传的命令+参数,接下来你给他赋值即可
'比方说ping.exe 如果你要ping 192.168.0.1 则代码如下:
aaa = "ping.exe" & " " & "192.168.0.1"
'关键是用引号引起字符串,用 & 连接字符串,遇到空格的时候用 " ",直到参数输完即可。当然参数也可以是变量,这样可以由用户指定,变量的使用方法在最后
'然后用shell方法启动指定的程序并传参数:
shell aaa
'同时可以指定程序执行的模式(有无焦点、是否最小化等等),一般无用,不再赘述。

//下面是变量使用方法
dim aaa as string, bbb as string
'定义两个字符串变量
bbb=text1.text
'假设有一个文本框让用户输入数据(本例为IP地址)
aaa="ping.exe" & " " & bbb
'注意bbb不加引号
shell aaa
'用shell方法启动程序,传递参数
'结束
【最新修改(开头)】
***我没有转移话题啊……只是新加了一些东西。请看【】中最后一句,只要把我原来的回答里aaa的内容改成【】里的即可。***
参考技术A 楼上的各位,你们都理解错了楼主的意思,他并不是要用VB程序来运行其它的命令,而是要用VB来制作一个控制台程序!
cmd的学名就叫做控制台,一般用VB做的程序默认是GUI(图形用户界面)的,而楼主想做一个在控制台中运行的文字用户界面程序
不过我十分奇怪楼主为什么刻意要用VB做,C/C++不是更好吗?用C/C++默认做出来的程序就是控制台的,用VB将极其麻烦,要调用很多Windows API函数
----------------------------------------
下面我给出一个例子,运行它就会在控制台(就是你说的cmd)里面打出What''s your name?在光标后输入名字后回车,如果没输入名字将显示You don''t have a name?如果输入名字将会打招呼
其实程序本身不复杂,程序的前面一大半都是Windows API函数的声明,这些声明都是现成的,直接用就可以了
-----------------------------------------
新建一个工程,然后在右边把默认的那个窗体删除掉,一定要删除,然后菜单----工程----添加模块,把下面代码拷贝到新建的模块代码里面就可以了
=========================================
Option Explicit
'' API函数声明
Private Declare Function AllocConsole Lib "kernel32" () As Long
Private Declare Function FreeConsole Lib "kernel32" () As Long
Private Declare Function GetStdHandle Lib "kernel32" (ByVal nStdHandle As Long) As Long
Private Declare Function ReadConsole Lib "kernel32" Alias "ReadConsoleA" (ByVal hConsoleInput As Long, ByVal lpBuffer As String, ByVal nNumberOfCharsToRead _
As Long, lpNumherOfCharsRead As Long, lpReserved As Any) As Long
Private Declare Function WriteConsole Lib "kernel32" Alias "WriteConsoleA" (ByVal hConsoleOutput As Long, ByVal lpBuffer As Any, ByVal nNumberOfCharsToWrite _
As Long, lpNumberOfCharsWritten As Long, lpReserved As Any) As Long
Private Declare Function SetConsoleMode Lib "kernel32" (ByVal hConsoleOutput As Long, dwMode As Long) As Long
Private Declare Function SetConsoleTitle Lib "kernel32" Alias "SetConsoleTitleA" (ByVal lpConsoleTitle As String) As Long
Private Declare Function SetConsoleTextAttribute Lib "kernel32" (ByVal hConsoleOutput As Long, ByVal wAttributes As Long) As Long
''定义API函数中用到的所有常量
''GetStdHandle函数的 nStdHandle参数的取值
Private Const STD_INPUT_HANDLE = -10&
Private Const STD_OUTPUT_HANDLE = -11&
Private Const STD_ERROR_HANDLE = -12&
''SetConsoleTextAttribute函数的wAttributes参数的取值(按RGB方式组合)
Private Const FOREGROUND_bLUE = &H1
Private Const FOREGROUND_GREEN = &H2
Private Const FOREGROUND_RED = &H4
Private Const FOREGROUND_INTENSITY = &H8
Private Const BACKGROUND_BLUE = &H10
Private Const BACKGROUND_GREEN = &H20
Private Const BACKGROUND_RED = &H40
Private Const BACKGROUND_INTENSITY = &H80
''SetConsoleMode的输入模式
Private Const ENABLE_LINE_INPUT = &H2
Private Const ENABLE_ECHO_INPUT = &H4
Private Const ENABLE_MOUSE_INPUT = &H10
Private Const ENABLE_PROCESSED_INPUT = &H1
Private Const ENABLE_WINDOW_INPUT = &H8
''SetConsoleMode的输出模式
Private Const ENABLE_PROCESSED_OUTPUT = &H1
Private Const ENABLE_WRAP_AT_EOL_OUTPUT = &H2
Private hConsoleIn As Long ''控制台窗口的 input handle
Private hConsoleOut As Long ''控制台窗口的output handle
Private hConsoleErr As Long ''控制台窗口的error handle
''主程序
Private Sub Main()
Dim szUserInput As String
AllocConsole ''创建 console window
SetConsoleTitle "VB控制台应用程序"
''设置console window的标题
''取得console window的三个句柄
hConsoleIn = GetStdHandle(STD_INPUT_HANDLE)
hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE)
hConsoleErr = GetStdHandle(STD_ERROR_HANDLE)
SetConsoleTextAttribute hConsoleOut, FOREGROUND_GREEN Or FOREGROUND_INTENSITY
''前景:亮绿;背景:黑
ConsolePrint "What''s your name?"
szUserInput = ConsoleRead()
If Not szUserInput = vbNullString Then
ConsolePrint "Hello, " & szUserInput & "!" & vbCrLf
Else
ConsolePrint "You don''t have a name?" & vbCrLf
End If
ConsolePrint vbCrLf & "Press enter to exit!"
Call ConsoleRead
FreeConsole ''销毁 console window
End Sub

''程序中用到的子函数
Private Sub ConsolePrint(szOut As String)
WriteConsole hConsoleOut, szOut, Len(szOut), vbNull, vbNull
End Sub

Private Function ConsoleRead() As String
Dim sUserInput As String * 256
Call ReadConsole(hConsoleIn, sUserInput, Len(sUserInput), vbNull, vbNull)
''截掉字符串结尾的&H00和回车、换行符
ConsoleRead = Left$(sUserInput, InStr(sUserInput, Chr$(0)) - 3)
End Function
参考技术B 楼主对这个问题很执着啊,为什么不能变通一点呢?
我觉得这个问题最大的关键在于不知道是谁调用了自己的程序,如果知道是哪个cmd调用了自己,那还可以用3楼的方法与它建立管道来实现相互通讯的目的
我想是否可以变通一下,如果程序打开时有cmd存在,就全都关闭掉,然后再shell一个出来,这样你想直接要shell时输出你要输出的内容,或是从shell的返回值,也就是此cmd窗口的pid,通过它确定窗口,再用API与之建立管道,这样不可以吗?

我给出一个简单的变通的例子,直接用shell和echo输出内容到一个cmd窗口

Private Sub Form_Initialize()
If Len(Command) Then
Shell "taskkill /f /im cmd.exe"
t = Timer
Delay:
DoEvents
If Timer < t + 1 Then GoTo Delay
Shell "cmd /k echo " & "你传入的参数是:" & Command, vbNormalFocus
End
End If
End Sub
参考技术C 方法1:
在VB中调用DOS,而且要将执行的结果反回给VB是不是?
这样写,呵呵,比如把dir c: 查询的结果返回给vb
1.调用DOS,将执行结果保存到C:\dir.txt里

Shell "cmd /c dir c:>c:\dir.txt", vbHide

2.读到文件,把执行结果返回给vb
open "c:\dir.txt" for input as #1
line input #1,linetext '将第一行读到linetext里
close #1
然后分析就可以了,就知道DOS的执行结果了

方法2:
利用sendmessage函数,查看一下api手册就可以本回答被提问者采纳
参考技术D 这个代码勉强可以吧!就是不太好看~~
(也要删掉主窗体,添上模块,但其实也可以在窗体里使用的~~~)

Option Explicit
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Const WM_CHAR = &H102

Public Sub main()
Dim myHandle As Long, cmd As String
Dim i As Long
'获取Dos窗口的句柄
myHandle = FindWindow("ConsoleWindowClass", vbNullString)
'要发送的字符串
cmd = "echo 我恨cmd - - !"
For i = 1 To Len(cmd)
PostMessage myHandle, WM_CHAR, Asc(Mid$(cmd, i, 1)), 0
Next i
PostMessage myHandle, WM_CHAR, 13, 0
End Sub

VB postMessage

postMessage(Ghwnd, WM_KEYDOWN, &H41, &H0)
为什么返回值是 TRUE
而不 FALSE 呀
SendMessage(Ghwnd, WM_KEYDOWN, &H41, &H0)
就可以返回FALSE
在线等!
急!!!

参考技术A 1, PostMessage只把消息放入队列,不管其他程序是否处理都返回,然后继续执行,这是个异步消息投放函数。而SendMessage必须等待其他程序处理消息完了之后才返回,继续执行,这是个同步消息投放函数。而且,PostMessage的返回值表示PostMessage函数执行是否正确;而SendMessage的返回值表示其他程序处理消息后的返回值。这点大家应该都明白。

2, 如果在同一个线程内,PostMessage发送消息时,消息要先放入线程的消息队列,然后通过消息循环Dispatch到目标窗口。SendMessage发送消息时,系统直接调用目标窗口的消息处理程序,并将结果返回。SendMessage在同一线程中发送消息并不入线程消息队列。 如果在不同线程内。最好用PostThreadMessage代替PostMessage,他工作的很好。SendMessage发送消息到目标窗口所属的线程的消息队列,然后发送消息的线程等待(事实上,他应该还在做一些监测工作,比如监视QS_SENDMESSAGE标志),直到目标窗口处理完并且结果返回,发送消息的线程才继续运行。这是SendMessage的一般情况,事实上,处理过程要复杂的多。比如,当发送消息的线程监测到有别的窗口SendMessage一个消息到来时,他直接调用窗口处理过程(重入),并将处理结果返回(这个过程不需要消息循环中GetMessage等的支持)。

3, msdn: If you send a message in the range below WM_USER to the asynchronous message functions (PostMessage, SendNotifyMessage, and SendMessageCallback), its message parameters can not include pointers. Otherwise, the operation will fail. 如果发送的消息码在WM_USER之下(非自定义消息)且消息参数中带有指针,那么PostMessage,SendNotifyMessage,SendMessageCallback这些异步消息发送函数将会调用失败。 最好不要用PostMessage发送带有指针参数的消息。

以上是关于VB程序向CMD返回信息的主要内容,如果未能解决你的问题,请参考以下文章

vb执行DOS命令并返回结果

vb怎样直接调用dos命令执行的结果?

vb Shell怎么执行多条cmd命令

VB 调用Bartender打印问题

vb 知道窗口句柄以及怎样获得窗口上文本框和按钮句柄并传递信息

向 VB.Net 应用程序添加命令行参数