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

SYD8821是具有全球领先低功耗(RX 2.4mA @-94.5dBm灵敏度,TX 4.3mA @0dBm输出功率)的蓝牙低功耗SOC芯片,在极低电流下实现了优异的射频性能,搭配176kB SRAM,512kB flash,非常适合中高阶可穿戴、智能家居、物联网等低功耗应用具体可咨询:http://www.syd-tek.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读取句柄,这样两对组成两个匿名管道。




源码下载链接

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

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

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




C#语言实现

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

扫描二维码关注公众号,回复: 2676936 查看本文章

// 起初打算采用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. public partial class Form1 : Form
  14. {
  15. public Form1()
  16. {
  17. InitializeComponent();
  18. }
  19. Thread Target = null;
  20. string lastline = null;
  21. Process Pipe = new Process();
  22. delegate void SetTextCallBack(string text);
  23. void Form1_Load(object sender, EventArgs e) {
  24. CheckForIllegalCrossThreadCalls = true;
  25. Pipe.StartInfo.FileName = "cmd";
  26. Pipe.StartInfo.CreateNoWindow = true;
  27. Pipe.StartInfo.UseShellExecute = false;
  28. Pipe.StartInfo.RedirectStandardError = true;
  29. Pipe.StartInfo.RedirectStandardInput = true;
  30. Pipe.StartInfo.RedirectStandardOutput = true;
  31. Pipe.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
  32. Pipe.Start();
  33. Pipe.StandardInput.WriteLine( "");
  34. Target = new Thread( new ThreadStart( this.target));
  35. Target.Start();
  36. }
  37. void target() {
  38. while ( true) {
  39. var line = Pipe.StandardOutput.ReadLine();
  40. if ( this.textBox1.InvokeRequired) {
  41. this.BeginInvoke( new SetTextCallBack( this.SetText), new object[] { "\r\n" + line });
  42. }
  43. Thread.Sleep( 50);
  44. }
  45. }
  46. void SetText(string text) {
  47. lock ( this.textBox1) {
  48. if ( this.textBox1.TextLength <= 0) {
  49. text = text.Replace( "\r\n", null);
  50. }
  51. if ( this.lastline != text.Substring( 2)) {
  52. this.textBox1.AppendText(text);
  53. }
  54. }
  55. }
  56. void textBox1_KeyPress(object sender, KeyPressEventArgs e) {
  57. if (e.KeyChar == ( char)Keys.Enter) {
  58. this.lastline = this.textBox1.Text.Substring( this.textBox1.GetFirstCharIndexOfCurrentLine());
  59. var str = this.lastline.Substring( this.lastline.IndexOf( '>') + 1);
  60. Pipe.StandardInput.WriteLine(str);
  61. e.Handled = true;
  62. }
  63. else if(e.KeyChar == ( char)Keys.Back) {
  64. var str = this.textBox1.Text.Substring( this.textBox1.GetFirstCharIndexOfCurrentLine());
  65. if (str.Length > 1) {
  66. if (str.Substring(str.Length - 1) == ">") {
  67. e.Handled = true;
  68. }
  69. }
  70. }
  71. }
  72. private void Form1_FormClosed(object sender, FormClosedEventArgs e) {
  73. Target.Abort();
  74. Pipe.Kill(); // Pipe.WaitForExit();
  75. }
  76. }


猜你喜欢

转载自blog.csdn.net/chengdong1314/article/details/80870077
今日推荐