Windows下 C++ 实现匿名管道的读写操作
由于刚弄C++没多久,部分还不熟练,最近又由于开发需求要求实现与其他程序进行通信,瞬间就感觉想到了匿名通信。于是自己查阅了一下资料,实现了一个可读可写的匿名管道:
源代码大部分都有注释:
Pipe.h 文件
#pragma once
#include <iostream>
#include <windows.h>
using namespace std; class Pipe // 不可移植类,只限于 WindowsXP 以上 平台
{
private:
HANDLE hpiperead = NULL; //读入 匿名管道
HANDLE hpipewrite = NULL; //读入 匿名管道
HANDLE hpiperead2 = NULL; //写出 匿名管道
HANDLE hpipewrite2 = NULL; //写出 匿名管道
HANDLE hProHandle = NULL;
HANDLE hThrLoop = NULL;
HANDLE hThrisLoop = NULL;
SECURITY_ATTRIBUTES ai; //安全属性
PROCESS_INFORMATION pi; //进程信息
STARTUPINFOA si;
BOOL pipe = false;
INT status = 1; // 0 = 异常 1 = 正常 -1 = 错误 、
string errorString;
public:
void loop() ; //循环
void isloop() ; //循环
const BOOL isPipeOff() const; //管道是否是开启
const INT getStatus() const; //获取当前状况
const string & getError() const; //获取当前错误信息
const BOOL sendCommand(const char *); //执行命令
void setPipeOn(const BOOL); //设置管道是否开启
void setStatus(const INT, const char*); //用于设置错误信息
void setStatus(const INT); //重载,用于设置状态
Pipe( char * str); //管道执行的命令
~Pipe();
};
Pipe.cpp 文件
1 #include "Pipe.h"
2
3
4 DWORD __stdcall ThrPipeThreadRead(void *www)
5 {
6 Pipe * pipe = (Pipe *)www;
7 pipe->loop();
8 return 0;
9 //创建内核对象使用完之后一定记得关闭,有可能会产生内存泄露
10 }
11 DWORD __stdcall WaitPipe(void *www)
12 {
13 Pipe * pipe = (Pipe *)www;
14 pipe->isloop();
15 return 0;
16 }
17
18
19 Pipe::Pipe( char * com)
20 {
21 ai.nLength = sizeof(SECURITY_ATTRIBUTES);
22 ai.bInheritHandle = true;
23 ai.lpSecurityDescriptor = NULL;
24 if (!CreatePipe(&hpiperead, &hpipewrite, &ai, 0)) //创建读入管道
25 {
26
27 this->setStatus(-1, "[0x01]Read 流创建失效");
28 return;
29 }
30
31 if (!CreatePipe(&hpiperead2, &hpipewrite2, &ai, 0)) //创建读入管道
32 {
33
34 this->setStatus(-1, "[0x02]Write 流创建失效");
35 return;
36 }
37 GetStartupInfoA(&si); //获取当前进程的STARTUPINFO
38 si.cb = sizeof(STARTUPINFO);
39 si.hStdError = hpipewrite;
40 si.hStdOutput = hpipewrite;
41 si.hStdInput = hpiperead2;
42 si.wShowWindow = SW_SHOW;
43 si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
44
45 if (!(CreateProcessA(NULL, com, NULL, NULL, true, NULL, NULL, NULL, &si, &pi))) //创建隐藏的CMD进程
46 {
47 this->setStatus(-1, "[0x03] CreateProcess函数执行出错");
48 return;
49 }
50
51
52 DWORD dwThread = FALSE;
53 hThrLoop = CreateThread(NULL, 0, ThrPipeThreadRead, this, 0, &dwThread);//chuangjian
54 if (hThrLoop == false){
55 this->setStatus(-1, "[0x11] 线程创建失败 CreateThread LOOP 失败");
56 return;
57 }
58 hThrLoop = CreateThread(NULL, 0, WaitPipe, this, 0, &dwThread);//chuangjian
59 if (hThrLoop == false){
60 this->setStatus(-1, "[0x12] 线程创建失败 CreateThread ISLOOP失败");
61 return;
62 }
63 }
64
65
66
67
68 Pipe::~Pipe()
69 {
70 //创建内核对象使用完之后一定记得关闭,有可能会产生内存泄露
71 this->setPipeOn(false);
72 this->setStatus(-1);
73 CloseHandle(hThrisLoop);
74 CloseHandle(hThrLoop);
75 CloseHandle(hpipewrite);
76 CloseHandle(hpiperead);
77 CloseHandle(hpiperead2);
78 CloseHandle(hpipewrite2);
79 CloseHandle(pi.hProcess);
80 CloseHandle(pi.hThread);
81
82 }
83 const INT Pipe::getStatus() const
84 {
85 return this->status;
86 }
87
88 const string & Pipe::getError() const
89 {
90 return this->errorString;
91 }
92
93 const BOOL Pipe::isPipeOff() const
94 {
95 return pipe;
96 }
97
98 void Pipe::setPipeOn(const BOOL bools)
99 {
100 this->pipe = bools;
101 }
102
103 void Pipe::setStatus(const INT status, const char * info)
104 {
105 this->errorString = info; //你说会不会有更好的赋值方法?
106 this->status = status;
107 }
108
109 void Pipe::setStatus(const INT status = 1)
110 {
111 this->status = status;
112 }
113
114 const BOOL Pipe::sendCommand(const char * com) //执行命令
115 {
116 DWORD dwWrite = 0;
117 char www[1024];
118 strcpy_s(www,com);
119 strcat_s(www,"\n");
120 return WriteFile(hpipewrite2, www, strlen(www), &dwWrite, NULL);
121 //0x001C7796 处有未经处理的异常(在 ConsoleApplication2.exe 中): 0xC0000005: 读取位置 0x0000000C 时发生访问冲突。
122 }
123
124 void Pipe::loop(){
125 char outbuff[4096]; //输出缓冲
126 DWORD byteread;
127 this->setPipeOn(true);
128 while (true)
129 {
130 memset(outbuff, '\0', 4096);
131 if (ReadFile(this->hpiperead, outbuff, 4095, &byteread, NULL) == NULL)
132 {
133 this->setPipeOn(false);
134 break;
135 }
136 printf("%s", outbuff);
137 memset(outbuff, '\0', 4096);
138 }
139 this->setPipeOn(false);
140 std::cout << "Pipe Stoped!"<<endl;
141 }
142
143 void Pipe::isloop()
144 {
145 DWORD dwRet = WaitForSingleObject(pi.hProcess, INFINITE);
146 while (dwRet == WAIT_TIMEOUT)
147 {
148 dwRet = WaitForSingleObject(pi.hProcess, INFINITE);
149 }
150
151 if (dwRet == WAIT_OBJECT_0 || dwRet == WAIT_ABANDONED)
152 {
153 this->setPipeOn(false);
154 std::cout << "[END] Pipe Stoped!" << endl;
155 }
156 }
Luncher.cpp
1 // ConsoleApplication2.cpp : 定义控制台应用程序的入口点。
2 //
3 #include <windows.h>
4 #include <thread>
5 #include "Pipe.h"
6 using namespace std;
7
8 void read();
9 void Loop();
10
11 Pipe * pipe; //属于全局变量
12
13
14 int Luncher() //那个啥,你就是当作这是Main文件的Main方法不
15 {
16 thread t1(read); //需要C++11标准
17 thread t2(Loop);
18
19 pipe = new Pipe("cmd");
20 t1.join();
21 t2.join();
22 return 0;
23 }
24 void read(){
25
26 while (true){
27 char str[200];
28 cin >> str;
29 pipe->sendCommand(str); //提交命令
30 }
31 }
32
33 void Loop(){
34 while (true)
35 {
36 Sleep(1000);
37 if (pipe->getStatus() == -11)
38 {
39 cout << " ERROR " << endl;
40 return;
41 }
42 }
43 }
这样即可实现 与任何程序进行交互:当然了也可以不仅仅是 输入输出
我们这里执行cmd;
结果:
并且可以进行交互:
差不多就这样,大神勿喷,我才刚弄C++
Windows下 C++ 实现匿名管道的读写操作的更多相关文章
- 解决windows下的mysql匿名登陆无法使用mysql数据库的问题
原文:解决windows下的mysql匿名登陆无法使用mysql数据库的问题 我在windows下安装了mysql,但是不用密码就能登进去,而root明明是有密码的,我用select user()命令 ...
- windows下使用TortoiseGit代替Git命令行操作
windows下使用TortoiseGit代替Git命令行操作 大家在使用svn的时候,都非常喜欢使用小乌龟,也就是TortoiseSVN:那么git也有小乌龟版本,即TortoiseGit. 1.安 ...
- Windows下安装kubectl及Node和Pod操作常用命令
kubernetes通过kube-apiserver作为整个集群管理的入口.Apiserver是整个集群的主管理节点,用户通过Apiserver配置和组织集群,同时集群中各个节点同etcd存储的交互也 ...
- libevent实现对管道的读写操作
读管道: #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/t ...
- Qt下libusb-win32的使用(二)批量读写操作
一.概述 学习libusb-win32的使用.使用批量传输方式与USB开发板进行数据读.写操作.上位机使用Qt做界面, 使用USB开发板的端点2作为批量传输端点. 二.实现 代码比较简单,直接给出,如 ...
- windows 下使用批处理执行 postgresql 命令行操作
1.准备好命令文件 loraserver.sql create role loraserver_as with login password 'dbpassword'; create role lor ...
- linux内核情景分析之匿名管道
管道的机制由pipe()创建,由pipe()所建立的管道两端都在同一进程.所以必须在fork的配合下,才可以在具有亲缘关系的进程通信 /* * sys_pipe() is the normal C c ...
- C语言的可变参数在Linux(Ubuntu)与Windows下注意点
基本上C语言的可变参数原理在不同平台和不同编译器下基本类似(通过函数入栈,从右向左,从高位到低位地址),不过部分实现会有所不同:在使用中需要注意的是: va_list 为char 类型指针,部分调用如 ...
- windows下的socket网络编程
windows下的socket网络编程 windows下的socket网络编程 clinet.c 客户端 server.c 服务器端 UDP通信的实现 代码如下 已经很久没有在windows下编程了, ...
随机推荐
- 学习之路三十九:新手学习 - Windows API
来到了新公司,一开始就要做个程序去获取另外一个程序里的数据,哇,挑战性很大. 经过两周的学习,终于搞定,主要还是对Windows API有了更多的了解. 文中所有的消息常量,API,结构体都整理出来了 ...
- android 监听软键盘的收起与打开
参考: http://toughcoder.net/blog/2015/10/09/android-trick-detect-soft-keyboard-show-slash-hide/ packag ...
- 7个惊艳的HTML5 Canvas动画效果及源码
HTML5非常强大,尤其是现在大部分浏览器都支持HTML5和CSS3,用HTML5制作的动画也多了起来.另外,Canvas上绘制图形非常简单,本文就分享了一些强大的HTML5 Cnavas动画,一起来 ...
- GitHub使用简单记录
根据<GotGitHub>[1]所做的一些整理 1. 浏览托管项目 在GitHub的页面中可以使用键盘快捷键 (1)按下问号(?)会在弹出窗口显示当前页面可用的快捷键. (2)在项目的代码 ...
- JavaWeb(李兴华著)开发笔记
1.Java语法-基础 环境变量-JAVA_HOME, PATH, ClassPath 变量名 作用 举例 JAVA_HOME 指向JDK目录 C:\Program Files\Java\jdk1.7 ...
- C头文件和源文件的连
(http://blog.163.com/yui_program/blog/static/18415541520115177852896/) 一.源文件如何根据#include来关联头文件 1,系统自 ...
- PowerPoint 打开文档发现.pptx中胡内容有问题
一.问题的提出 有一个文件,在window 7操作系统中通过邮箱地址保存到本地,结果打开的时候出现[PowerPoint 打开文档发现 文件.pptx中胡内容有问题] 然后提示[如果您信任此演示文稿的 ...
- nginx url自动加斜杠的问题
nginx url自动加斜杠问题及301重定向 时间:2016-02-04 15:14:28来源:网络 导读:nginx url自动加斜杠问题及301重定向,URL指向一个目录并且在最后没有包含斜杠, ...
- Winform快速开发组件的实现(一)
好久好久没有露面了,呵呵,对于写文章都有点生疏了. 在拿到任何一个项目,不管是b/s的还是c/s,我不会立即开始写代码,我一般会为使这些项目能够快速开发制定一系列的支持组件,虽然可能前期会付出一些代价 ...
- js判断手机浏览器并跳转到手机网站
function uaredirect(murl){ try { if(document.getElementById("bdmark") != null){ return; } ...