#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h> int Call(char Cmd[])
{
SECURITY_ATTRIBUTES sa;
HANDLE Hread,Hwrite;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if (!CreatePipe(&Hread,&Hwrite,&sa,0))
{
printf("Create Pipe in error\r\n");
return 0;
} STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si,sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = Hwrite;
si.hStdOutput = Hwrite;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
memset(&pi,0,sizeof(PROCESS_INFORMATION));
char cmdline[1024 ] = "cmd /c";
strcat(cmdline,Cmd);
if (!CreateProcessA(NULL,cmdline,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))
{
printf("Create process error\r\n");
return 0;
} CloseHandle(Hwrite); char buff[1024] = {0};
//char cres[MAX_PATH] = {0};
DWORD bytesread;
while (true)
{
if (ReadFile(Hread,buff,1024,&bytesread,NULL) == NULL)
{
break;
} int ilen = strlen(buff);
for (int i =0;i<ilen;i++)
{
if (buff[i] == '\n' || buff[i] == '\r')
{
buff[i] = '\0';
}
}
printf(buff);
}
CloseHandle(Hread);
//sprintf() return 0;
} int _tmain(int argc, _TCHAR* argv[])
{
char* Cmd = argv[1];
Call(Cmd);
return 0;
} 使用管道CREATEPIPE,来进行进程间的相互通信,然后在进行数据的读取。 什么是管道,管道就是一种通信机制,也就是内存共享,一个进程向管道写入数据后,由另外一个管道读出。  匿名管道是在父进程和子进程间单向传输数据的一种未命名的管道,只能在本地计算机中使用,而不可用于网络间的通信。

匿名管道由CreatePipe()函数创建,该函数在创建匿名管道的同时返回两个句柄:管道读句柄和管道写句

柄。CreatePipe()的函数原型为:
BOOL CreatePipe(
      PHANDLE hReadPipe,    // 指向读句柄的指针
   PHANDLE hWritePipe, &nb sp;  // 指向写句柄的指针
   LPSECURITY_ATTRIBUTES lpPipeAttributes,  // 指向安全属性的指针
   DWORD nSize     // 管道大小
  );   
返回值   
Long,非零表示成功,零表示失败。会设置GetLastError

在调用CreatePipe()函数时,如果管道服务器将lpPipeAttributes 指向的SECURITY_ATTRIBUTES数据结构的数据成员bInheritHandle设置为TRUE,那么CreatePipe()创建的管道读、写句柄将会被继承。
    在用WriteFile()函数向管道写入数据时,只有在向管道写完指定字节的数据后或是在有错误发生时函数才会返回。如管道缓冲已满而数据还没有写完,WriteFile()将要等到另一进程对管道中数据读取以释放出更多可用空间后才能够返回。管道服务器在调用CreatePipe()创建管道时以参数nSize对管道的缓冲大小作了设定。
  匿名管道并不支持异步读、写操作,这也就意味着不能在匿名管道中使用ReadFileEx()和WriteFileEx(),而且ReadFile()和WriteFile()中的lpOverLapped参数也将被忽略。匿名管道将在读、写句柄都被关闭后退出,也可以在进程中调用CloseHandle()函数来关闭此句柄。

程序具体实现过程:
(1) 初始化安全属性的指针 //创建匿名管道前期,就得初始化安全属性的指针。
 SECURITY_ATTRIBUTES sa;
 sa.nLength = sizeof(sa);
 sa.lpSecurityDescriptor = 0;
 sa.bInheritHandle = TRUE;

(2) 创建匿名管道 //开始创建匿名管道
 HANDLE hReadPipe1,hWritePipe1;
 CreatePipe(&hReadPipe1,&hWritePipe1,&sa,0);

(3) 创建cmd进程
BOOL CreateProcess(   
 LPCTSTR lpApplicationName,      //可执行模块的字符串 
 LPTSTR lpCommandLine,      //执行的命令行字符串
 LPSECURITY_ATTRIBUTES lpProcessAttributes, 
 LPSECURITY_ATTRIBUTES lpThreadAttributes,   
 BOOL bInheritHandles,      //新进程是否从调用进程处继承了句柄
 DWORD dwCreationFlags,      //标志
 LPVOID lpEnvironment,      //新进程的环境块
 LPCTSTR lpCurrentDirectory,     //子进程的工作路径
 LPSTARTUPINFO lpStartupInfo,     //决定新进程的主窗体如何显示
 LPPROCESS_INFORMATION lpProcessInformation  //接收新进程的识别信息
  );

在创建进程前,先初始化两个结构体:LPSTARTUPINFO 和LPPROCESS_INFORMATION

STARTUPINFO结构用于指定新进程的主窗口特性,应用程序必须将cb初始化为sizeof(STARTUPINFO)
STARTF_USESHOWWINDOW使用wShowWindow成员:wShowWindow用于设定如果子应用程序初次调用的ShowWindows将SW_SHOWDEFAULT作为nCmdShow参数传递时,该应用程序的第一个重叠窗口应该如何出现。
STARTF_USESTDHANDLES使用hstdInput、hstdOutput和hstdError成员:HANDLE hStdInput用于设定供控制台输入和输出用的缓存的句柄。按照默认设置,hstdInput 用于标识键盘缓存,hstdOutput和hstdError用于标识控制台窗口的缓存。

STARTUPINFO si;
 memset(&si,0,sizeof(si));
 GetStartupInfo(&si);  //该函数返回进程在启动时被指定的STARTUPINFO 结构
 si.cb = sizeof(si);
 si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
 si.wShowWindow = SW_HIDE;
 si.hStdOutput = si.hStdError = hWritePipe1;

PROCESS_INFORMATION pInfo;
 memset(&pInfo,0,sizeof(PROCESS_INFORMATION));

创建进程
 char szCmd[MAXLENGTH] = "cmd.exe /c";
 //接收远程传入的进程执行参数
 int dwSize = ((RatProto*)szRecvCmd)->RatLen - sizeof(RatProto);
 strncat(szCmd,szRecvCmd+sizeof(RatProto),dwSize);
 CreateProcessA(NULL,szCmd,NULL,NULL,1,0,NULL,NULL,&si,&pInfo);

(3) 通过管道通信,得到进程执行结果
 memset(szCmd,0,MAXLENGTH);
 int dwRead;
 //判断管道内是否有传入数据
 int nRet = PeekNamedPipe(hReadPipe1,szCmd,MAXLENGTH,(LPDWORD)&dwRead,NULL,NULL);
 for (int i=0;i<5&&dwRead==0;i++)
 {
  Sleep(100);
  nRet = PeekNamedPipe(hReadPipe1,szCmd,MAXLENGTH,(LPDWORD)&dwRead,NULL,NULL);
 }

if (dwRead)
 {
  nRet = ReadFile(hReadPipe1,szCmd,dwRead,(LPDWORD)&dwRead,0);
  if (!nRet)
  {
   sprintf(szCmd,"%s","CMD COMMAND EXCUTE ERROR!");
  }  
 }

(4) 将执行结果传给客户端
 .......

VC 模拟CMD 匿名管道的更多相关文章

  1. 匿名管道读取CMD回显信息

    之前用了很坑爹的做法去读取了cmd命令的回显信息,现在发现了用匿名管道的实现方法,由于楼主没有学过Windows核心编程,找了一个代码来凑数 存下来以后研究 #include <windows. ...

  2. 通过匿名管道获取CMD运行结果

    #include <iostream> #include <string> #include <Windows.h> using namespace std; /* ...

  3. Windows下 C++ 实现匿名管道的读写操作

    由于刚弄C++没多久,部分还不熟练,最近又由于开发需求要求实现与其他程序进行通信,瞬间就感觉想到了匿名通信.于是自己查阅了一下资料,实现了一个可读可写的匿名管道: 源代码大部分都有注释: Pipe.h ...

  4. 使用匿名管道在进程间通信 (System.IO.Pipes使用)(转)

    原文地址:http://www.cnblogs.com/yukaizhao/archive/2011/08/04/system-io-pipes.html 管道的用途是在同一台机器上的进程之间通信,也 ...

  5. C语言通过匿名管道实现反弹式CMDShell

    #pragma comment(lib,"ws2_32.lib") #ifdef _MSC_VER #pragma comment( linker, "/subsyste ...

  6. Windows进程通信之一看就懂的匿名管道通信

    目录 进程通信之一看就懂的匿名管道通信 一丶匿名管道 1.1何为匿名管道 1.2创建匿名管道需要注意的事项 1.3 创建匿名管道需要的步骤 1.4代码例子 1.5代码运行截图 进程通信之一看就懂的匿名 ...

  7. 进程通信类型 管道是Linux支持的最初Unix IPC形式之一 命名管道 匿名管道

    管道 Linux环境进程间通信(一) https://www.ibm.com/developerworks/cn/linux/l-ipc/part1/index.html 管道及有名管道 郑彦兴200 ...

  8. Linux学习笔记(12)-进程间通信|匿名管道

    Linux的进程间通信有几种方式,包括,管道,信号,信号灯,共享内存,消息队列和套接字等-- 现在一个个的开始学习! ----------------------------------------- ...

  9. Linux进程间通信(三):匿名管道 popen()、pclose()、pipe()、close()、dup()、dup2()

    在前面,介绍了一种进程间的通信方式:使用信号,我们创建通知事件,并通过它引起响应,但传递的信息只是一个信号值.这里将介绍另一种进程间通信的方式——匿名管道,通过它进程间可以交换更多有用的数据. 一.什 ...

随机推荐

  1. python学习【第五篇】python函数 (二)

    一.装饰器 装饰器:本质就是函数,功能是为其它函数添加附加功能 装饰器的原则: 不修改被修饰函数的源代码 不修改被修饰函数的调用方式 装饰器的知识储备: 装饰器 = 高阶函数 + 函数嵌套 + 闭包 ...

  2. POJ3090

    Visible Lattice Points Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7094   Accepted: ...

  3. 【BZOJ3277/3473】串/字符串 后缀数组+二分+RMQ+双指针

    [BZOJ3277]串 Description 字符串是oi界常考的问题.现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(注意包括本身). Inpu ...

  4. Splitting Pile

    Splitting Pile Time limit : 2sec / Memory limit : 256MB Score : 300 points Problem Statement Snuke a ...

  5. 内置函数:min 用法

    内置函数:min 用法 源码 def min(*args, key=None): # known special case of min """ min(iterable ...

  6. Python3.6全栈开发实例[007]

    7.此函数只接收一个参数且此参数必须是列表数据类型,此函数完成的功能是返回给调用者一个字典,此字典的键值对为此列表的索引及对应的元素.例如传入的列表为:[11,22,33] 返回的字典为 {0:11, ...

  7. Python3.6全栈开发实例[001]

    检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者. li = [11,22,33,44,55,66,77,88,99,000,111,222] def func1(l ...

  8. python并发之IO模型(一)

    事件驱动模型 协程:遇到IO操作就切换. 但什么时候切回去呢?怎么确定IO操作完了? 很多程序员可能会考虑使用“线程池”或“连接池”.“线程池”旨在减少创建和销毁线程的频率,其维持一定合理数量的线程, ...

  9. 1、Python request(爬虫-百度翻译)

    #encoding=utf-8 import requests def fanyi(): while True: context = input("请输入翻译的内容(退出q):") ...

  10. LDA(Latent Dirichlet allocation)主题模型

    LDA是一种典型的词袋模型,即它认为一篇文档是由一组词构成的一个集合,词与词之间没有顺序以及先后的关系.一篇文档可以包含多个主题,文档中每一个词都由其中的一个主题生成. 它是一种主题模型,它可以将文档 ...