运用管道,通过ADB口发生指令 。

C#管道读取优化
本文分享了一个在C#中优化管道读取的方法,解决了使用内置函数时出现的卡死问题,通过调用Windows API函数实现了更稳定的管道内容读取。

  之前在做一个自动化项目的时候运动到了管道(Process),在开发过程中直接使用了C#封装好的方法。但是在实际运用过程中出现了一定的问题,在扫描管道内容时时常出现卡死的显现。之后再网络上查询了很久在另一篇博客中找到了问题,是C#函数存在一定的BUG。目前已经忘记了那位大神是谁了。不过还是要谢谢他。接下来分享下这个方法以便于其他与我遇到相同问题的朋友可以借鉴。如有不足之处也可以直接指出。

 

            /*变量定义*/
            Str_Result = string.Empty;
            int BufferCount = 0;
            byte[] rf_Buffer = new byte[4096];
            Process p = new Process();
            /*初始化管道*/
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.Arguments = string.Format("/c {0}", Str_Cmd);//命令
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            p.Start();//启动道
            p.WaitForExit(40000);//等待指令完成给定40秒正常指令都已经完成了

以上是管道的定义以及启动。

  // 将返回资料付给文件系统
            System.IO.FileStream TempStrem = (System.IO.FileStream)p.StandardOutput.BaseStream;
  uint StartTime = GetTickCount();//获取开始时间 用于超时跳出
            if (B_IsResult)
            {

                do
                {
                    // C#扫描存在BUG 沿用API函数
                    //最开始运用的C#封装好的函数但是一直会出现卡死后运用windowsAPI函数不知到4.0以后版本是否优化
                    BufferCount = 0;
                    PeekNamedPipe(TempStrem.SafeFileHandle, rf_Buffer, 65535, ref BufferCount, 0, 0);
                    if (BufferCount > 0)
                    {
                        break;//如果管道内已经为空则跳出
                    }
                } while (B_IsResult && (GetTickCount() - StartTime < I_TimeOut));

                while (B_IsResult)//判断如果需要内容这读取
                {
                      //这里可能有点小问题 
                      //如果不需要判断返回值没有读取管道内的值则可能会出现管道无法关闭
                    BufferCount = 0;
                    PeekNamedPipe(TempStrem.SafeFileHandle, rf_Buffer, 65535, ref BufferCount, 0, 0);
                    if (BufferCount > 0)//如果扫描到管道内有值则读取
                    {
                        byte[] c_Buffer = new byte[BufferCount];
                        TempStrem.Read(c_Buffer, 0, BufferCount);
                        string temp_Result = System.Text.Encoding.Default.GetString(c_Buffer);//转换为中文
                        Str_Result += temp_Result;
                    }
                    else
                    {
                        break;
                    }
                    Thread.Sleep(50);
                }
            }

以上为管道返回内容的读取

 p.Close();
 p.Dispose();//关闭并释放

以上为管道的关闭释放

 [DllImport("kernel32.dll", SetLastError = true)]
        public static extern int PeekNamedPipe(//API函数扫描管道
         SafeFileHandle hNamedPipe,
         byte[] lpBuffer,
         int nBufferSize,
         ref int lpBytesRead,
         int lpTotalBytesAvail,
         int lpBytesLeftThisMessage
         );

        [DllImport("kernel32")]
        public static extern uint GetTickCount();//API函数获取时间

以上运用的API函数

转载于:https://www.cnblogs.com/MageChen/p/6074061.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值