VC 模拟CMD 匿名管道
#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 匿名管道的更多相关文章
- 匿名管道读取CMD回显信息
之前用了很坑爹的做法去读取了cmd命令的回显信息,现在发现了用匿名管道的实现方法,由于楼主没有学过Windows核心编程,找了一个代码来凑数 存下来以后研究 #include <windows. ...
- 通过匿名管道获取CMD运行结果
#include <iostream> #include <string> #include <Windows.h> using namespace std; /* ...
- Windows下 C++ 实现匿名管道的读写操作
由于刚弄C++没多久,部分还不熟练,最近又由于开发需求要求实现与其他程序进行通信,瞬间就感觉想到了匿名通信.于是自己查阅了一下资料,实现了一个可读可写的匿名管道: 源代码大部分都有注释: Pipe.h ...
- 使用匿名管道在进程间通信 (System.IO.Pipes使用)(转)
原文地址:http://www.cnblogs.com/yukaizhao/archive/2011/08/04/system-io-pipes.html 管道的用途是在同一台机器上的进程之间通信,也 ...
- C语言通过匿名管道实现反弹式CMDShell
#pragma comment(lib,"ws2_32.lib") #ifdef _MSC_VER #pragma comment( linker, "/subsyste ...
- Windows进程通信之一看就懂的匿名管道通信
目录 进程通信之一看就懂的匿名管道通信 一丶匿名管道 1.1何为匿名管道 1.2创建匿名管道需要注意的事项 1.3 创建匿名管道需要的步骤 1.4代码例子 1.5代码运行截图 进程通信之一看就懂的匿名 ...
- 进程通信类型 管道是Linux支持的最初Unix IPC形式之一 命名管道 匿名管道
管道 Linux环境进程间通信(一) https://www.ibm.com/developerworks/cn/linux/l-ipc/part1/index.html 管道及有名管道 郑彦兴200 ...
- Linux学习笔记(12)-进程间通信|匿名管道
Linux的进程间通信有几种方式,包括,管道,信号,信号灯,共享内存,消息队列和套接字等-- 现在一个个的开始学习! ----------------------------------------- ...
- Linux进程间通信(三):匿名管道 popen()、pclose()、pipe()、close()、dup()、dup2()
在前面,介绍了一种进程间的通信方式:使用信号,我们创建通知事件,并通过它引起响应,但传递的信息只是一个信号值.这里将介绍另一种进程间通信的方式——匿名管道,通过它进程间可以交换更多有用的数据. 一.什 ...
随机推荐
- 错误命令“if not exist "\Dll" mkdir "\Dll" xcopy "\bin\Debug\*.*" "F:\647\VS项目\EtrolMes2014SY\Framework\Dll" /e /i /y”已退出,代码为 9009
分析错误 第一步:观察错误,发现plugin文件夹中未生成对应的编译文件. 第二步:XCOPY命令无法执行,百度xcopy为何无法执行 第三步,搜索,发现环境变量未配置正确. 就是环境变量path(大 ...
- SQL Server 还原错误“restore database正在异常终止 错误 3154”
今天在还原数据库时,先建立相同名字的数据库,然后在该数据库上右键还原数据库.遇到了这样的一个错误: “备份集中的数据库备份与现有的 'RM_DB' 数据库不同. RESTORE DATABASE 正在 ...
- [Docker]学习笔记--简单介绍
学习docker已经有一段时间了,一直没有静下心来好好总结一下. 最近用docker搭了一整套Gitlab的持续集成环境.(会在下一篇中详细的讲解具体步骤,敬请期待) 感觉是时候写点东西和大家一起分享 ...
- echarts系列之动态加载数据
1.echarts学习前言 最近接触到echarts,发现数据可视化真的是魅力无穷啊,各种变幻的曲线交错,以及‘曼妙’的动画效果真是让人如痴如醉! 下面就来一起欣赏她的美... “ ECharts是中 ...
- EM算法(expectation maximization)
EM算法简述 EM算法是一种迭代算法,主要用于含有隐变量的概率模型参数的极大似然估计,或极大后验概率估计.EM算法的每次迭代由两步完成: E步,求期望 M步,求极大. EM算法的引入 如果概率模型的变 ...
- Python之常用模块(re,时间,random,os,sys,序列化模块)(Day20)
一.时间模块 #常用方法 1.time.sleep(secs) (线程)推迟指定的时间运行.单位为秒. 2.time.time() 获取当前时间戳 在Python中表示时间的三种方式:时间戳,元组(s ...
- windows安装pywin32
下载旧版 https://sourceforge.net/projects/pywin32/files/pywin32/ 下载新版 https://github.com/mhammond/pywin3 ...
- 推荐一款轻量级PHP数据库框架–Medoo
引用官网的简介: 可以加快开发速度的最轻量级的PHP数据库框架 为什么选择Medoo及其主要功能: 轻量级–单个文件,只有20KB 易用–非常容易学习和使用 功能强大–支持各种常见和复杂的SQL查询 ...
- iOS 结构简单清晰的 设置页面
这个是也是看了人家的代码,觉得甚是简单清晰,也是比较容易扩展.拿来学习一下 效果展示: 重点有以下2处: 1 .建立groupModel 列清组元素:当前组list 集合, 是否有header 或者 ...
- 8.22 ps课堂练习
真是做得超烂!以前学的快忘光了!