【匿名管道】重定向cmd.exe【C#语言实现】

SYD8821是具有全球领先低功耗(RX 2.4mA @-94.5dBm灵敏度,TX 4.3mA @0dBm输出功率)的蓝牙低功耗SOC芯片,在极低电流下实现了优异的射频性能,搭配176kB SRAM,512kB flash,非常适合中高阶可穿戴、智能家居、物联网等低功耗应用具体可咨询:http://www.sydtek.com/

 

本文摘录于:https://blog.csdn.net/yzt33/article/details/44516493,这里只是作为一个我的一个抄录版,绝对没有盗用前辈知识的意图。

 

 

匿名管道通信——重定向CMD.EXE

 

 

匿名管道

匿名管道无非就是系统内核管理的一块内存区域,把这个文件的句柄分为读写,以程序使用。

 

 

实现原理

所以重定向cmd.exe的标准输入输出分别为两个匿名管道的输入输出即可。在GUI中对应接收和写入内容(不要搞错啦这里,否则就读不到正确的东西)。

 

 

程序大致过程

①、匿名管道创建

 
  1. BOOL WINAPI CreatePipe(

  2. _Out_ PHANDLE hReadPipe, //匿名管道读句柄

  3. _Out_ PHANDLE hWritePipe, //匿名管道写句柄

  4. _In_opt_ LPSECURITY_ATTRIBUTES lpPipeAttributes, //这里需要设置这个结构体(见下)

  5. _In_ DWORD nSize //管道空间,设为0即默认大小

  6. );

 
  1. typedef struct _SECURITY_ATTRIBUTES {

  2. DWORD nLength;

  3. LPVOID lpSecurityDescriptor;

  4. BOOL bInheritHandle;

  5. } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;


②、打开cmd.exe子进程

 
  1. BOOL WINAPI CreateProcess(

  2. _In_opt_ LPCTSTR lpApplicationName,//执行模块位置

  3. _Inout_opt_ LPTSTR lpCommandLine,//执行模块传入命令

  4. _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,

  5. _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,

  6. _In_ BOOL bInheritHandles,//继承句柄

  7. _In_ DWORD dwCreationFlags,

  8. _In_opt_ LPVOID lpEnvironment,

  9. _In_opt_ LPCTSTR lpCurrentDirectory,

  10. _In_ LPSTARTUPINFO lpStartupInfo,//启动信息(见下)

  11. _Out_ LPPROCESS_INFORMATION lpProcessInformation//进程信息(为空即可)

  12. );

 

 
  1. typedef struct _STARTUPINFO {//此处只写本次索要用到的

  2. DWORD cb;//大小

  3. LPTSTR lpReserved;

  4. LPTSTR lpDesktop;

  5. LPTSTR lpTitle;

  6. DWORD dwX;

  7. DWORD dwY;

  8. DWORD dwXSize;

  9. DWORD dwYSize;

  10. DWORD dwXCountChars;

  11. DWORD dwYCountChars;

  12. DWORD dwFillAttribute;

  13. DWORD dwFlags;//STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW显示自己设置的模式

  14. WORD wShowWindow;

  15. WORD cbReserved2;

  16. LPBYTE lpReserved2;

  17. HANDLE hStdInput;//标准输入句柄

  18. HANDLE hStdOutput;//标准输出句柄

  19. HANDLE hStdError;//标准错误句柄

  20. } STARTUPINFO, *LPSTARTUPINFO;

 

到这里其实已经都配置完了,无非是自己再写个多线程让UI和WORKER分开运行,读取和写入。值得提醒的是,对于cmd.exe的写入时,需要在字符串后+“\r\n”,刷新缓冲。这里把CreatePipe写出来,防止弄混:GUI读取句柄+CMD.EXE写入句柄,GUI写入句柄+CMD.EXE读取句柄,这样两对组成两个匿名管道。

 

 

 

源码下载链接

http://download.csdn.net/detail/yzt33/8521139

很喜欢编程,喜欢深入了解一切的实现,作为新人,希望前辈们多多指正,多多鼓励,谢谢。

    这个例程是我测试过绝对可以跑起来的代码!

    不过,该例程是C++语言编写的!

 

 

 

 

C#语言实现

C#也是可以实现DOC回显的,可看如下代码(摘录于:https://blog.csdn.net/windowsvipcuvs/article/details/38143939):

 

// 起初打算采用CreatePipe创建匿名管道来着,不过却无法得到int&hReadPipe返回参数

// 后来只有利用Net库自身来实现这个东西了

// 下面是一个CreatePipe函数参数的定义形式

 
  1. namespace Pipe

  2. {

  3. using System;

  4. using System.Collections.Generic;

  5. using System.ComponentModel;

  6. using System.Data;

  7. using System.Drawing;

  8. using System.Text;

  9. using System.Windows.Forms;

  10. using System.IO;

  11. using System.Threading;

  12. using System.Diagnostics;

  13.  
  14. public partial class Form1 : Form

  15. {

  16. public Form1()

  17. {

  18. InitializeComponent();

  19. }

  20. Thread Target = null;

  21. string lastline = null;

  22. Process Pipe = new Process();

  23. delegate void SetTextCallBack(string text);

  24. void Form1_Load(object sender, EventArgs e) {

  25. CheckForIllegalCrossThreadCalls = true;

  26. Pipe.StartInfo.FileName = "cmd";

  27. Pipe.StartInfo.CreateNoWindow = true;

  28. Pipe.StartInfo.UseShellExecute = false;

  29. Pipe.StartInfo.RedirectStandardError = true;

  30. Pipe.StartInfo.RedirectStandardInput = true;

  31. Pipe.StartInfo.RedirectStandardOutput = true;

  32. Pipe.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

  33. Pipe.Start();

  34. Pipe.StandardInput.WriteLine("");

  35. Target = new Thread(new ThreadStart(this.target));

  36. Target.Start();

  37. }

  38. void target() {

  39. while (true) {

  40. var line = Pipe.StandardOutput.ReadLine();

  41. if (this.textBox1.InvokeRequired) {

  42. this.BeginInvoke(new SetTextCallBack(this.SetText), new object[] { "\r\n" + line });

  43. }

  44. Thread.Sleep(50);

  45. }

  46. }

  47. void SetText(string text) {

  48. lock (this.textBox1) {

  49. if (this.textBox1.TextLength <= 0) {

  50. text = text.Replace("\r\n", null);

  51. }

  52. if (this.lastline != text.Substring(2)) {

  53. this.textBox1.AppendText(text);

  54. }

  55. }

  56. }

  57. void textBox1_KeyPress(object sender, KeyPressEventArgs e) {

  58. if (e.KeyChar == (char)Keys.Enter) {

  59. this.lastline = this.textBox1.Text.Substring(this.textBox1.GetFirstCharIndexOfCurrentLine());

  60. var str = this.lastline.Substring(this.lastline.IndexOf('>') + 1);

  61. Pipe.StandardInput.WriteLine(str);

  62. e.Handled = true;

  63. }

  64. else if(e.KeyChar == (char)Keys.Back) {

  65. var str = this.textBox1.Text.Substring(this.textBox1.GetFirstCharIndexOfCurrentLine());

  66. if (str.Length > 1) {

  67. if (str.Substring(str.Length - 1) == ">") {

  68. e.Handled = true;

  69. }

  70. }

  71. }

  72. }

  73. private void Form1_FormClosed(object sender, FormClosedEventArgs e) {

  74. Target.Abort();

  75. Pipe.Kill(); // Pipe.WaitForExit();

  76. }

  77. }

  78.  

 

 

 

 

 

在Windows操作系统中,可以使用匿名管道重定向实现输出cmd命令执行结果。具体步骤如下: 1. 创建一个匿名管道,使用CreatePipe函数实现。 2. 创建一个子进程,使用CreateProcess函数实现。在子进程中,将管道的输出重定向到标准输出。 3. 在父进程中,使用ReadFile函数读取管道中的数据,即子进程输出的结果。 下面是一个示例代码: ``` #include <windows.h> #include <stdio.h> int main() { HANDLE hReadPipe, hWritePipe; SECURITY_ATTRIBUTES saAttr; PROCESS_INFORMATION piProcInfo; STARTUPINFO siStartInfo; BOOL bSuccess; DWORD dwRead; // 创建匿名管道 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; if(!CreatePipe(&hReadPipe, &hWritePipe, &saAttr, 0)) { printf("CreatePipe failed\n"); return 1; } // 创建子进程 ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION)); ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); siStartInfo.cb = sizeof(STARTUPINFO); siStartInfo.hStdError = hWritePipe; siStartInfo.hStdOutput = hWritePipe; siStartInfo.dwFlags |= STARTF_USESTDHANDLES; bSuccess = CreateProcess(NULL, "ipconfig", NULL, NULL, TRUE, 0, NULL, NULL, &siStartInfo, &piProcInfo); if(!bSuccess) { printf("CreateProcess failed\n"); return 1; } // 读取子进程输出的结果 CHAR chBuf[1024]; ZeroMemory(chBuf, sizeof(chBuf)); for (;;) { bSuccess = ReadFile(hReadPipe, chBuf, sizeof(chBuf), &dwRead, NULL); if(!bSuccess || dwRead == 0) break; printf("%s", chBuf); ZeroMemory(chBuf, sizeof(chBuf)); } // 关闭句柄 CloseHandle(hReadPipe); CloseHandle(hWritePipe); CloseHandle(piProcInfo.hProcess); CloseHandle(piProcInfo.hThread); return 0; } ``` 上述代码中,使用了ipconfig命令作为示例,可以根据实际需求替换为其他命令。运行程序后,会输出ipconfig命令的执行结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值