如何从 System.Diagnostics.Process 停止进程并最终获取统计信息

Posted

技术标签:

【中文标题】如何从 System.Diagnostics.Process 停止进程并最终获取统计信息【英文标题】:How to stop a process from System.Diagnostics.Process and get the statistics in the end 【发布时间】:2017-08-11 20:29:00 【问题描述】:

我正在使用这段代码,但是当我停止进程时,它没有得到 ping 统计信息:

System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = "ping";
p.StartInfo.Arguments = "-c " + count + " -i " + interval + " -s " + buffer + " -W " + timeout + " " + address;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;

string readData = "";

DateTime dt = DateTime.Now.AddSeconds(5);
if (p.Start())

    Scanner scanner = new Scanner(p.StandardOutput.BaseStream);

    while (scanner.HasNextLine)
    
        readData =  scanner.NextLine().ToString();
        Console.WriteLine(readData.ToString());

        if (!string.IsNullOrEmpty(readData) && !readData.StartsWith("---"))
        
            Match M = Regex.Match(readData, @"^[\d]+ bytes from ([^:]+): [^ ]+ ttl=([\d]+) time=([^ ]+) ms");

            if (M != null && M.Success)
            
                string IP = M.Groups[1].Value;
                string TTL = M.Groups[2].Value;
                string timeStr = M.Groups[3].Value;

                Console.WriteLine(String.Format("Ping to 0 took 2 ms with a ttl of 1", IP, TTL, timeStr));
                // Parsing the timeStr will work the same way as above
               if(dt > DateTime.Now)
               
                   p.StandartInput.Write("\x3");
                
            
            else
            
                Match M1 = Regex.Match(readData, @"^rtt [^0-9]*([\d][^\/]+)\/([^\/]+)\/([^\/]+)\/([^ ]+) ms$");

                if (M1 != null && M1.Success)
                
                    float avgPingTime = 0;
                    float maxPingTime = 0;
                    float minPingTime = 0;

                    string minPingString = M1.Groups[1].Value;
                    string avgPingString = M1.Groups[2].Value;
                    string maxPingString = M1.Groups[3].Value;

                    // Now parse that value
                    float.TryParse(minPingString, System.Globalization.NumberStyles.Float, System.Globalization.NumberFormatInfo.InvariantInfo, out minPingTime);
                    float.TryParse(avgPingString, System.Globalization.NumberStyles.Float, System.Globalization.NumberFormatInfo.InvariantInfo, out avgPingTime);
                    float.TryParse(maxPingString, System.Globalization.NumberStyles.Float, System.Globalization.NumberFormatInfo.InvariantInfo, out maxPingTime);

                    Console.WriteLine(String.Format("Min Time : 0 , AVG 2 ms, Max Time 1", minPingTime, maxPingTime, avgPingTime));
                
            
        
    

不使用

if(dt > DateTime.Now)

     p.StandartInput.Write("\x3");

结果显示如下:

64 bytes from 8.8.8.8: icmp_req=1 ttl=46 time=13.9 ms
64 bytes from 8.8.8.8: icmp_req=2 ttl=46 time=13.9 ms
64 bytes from 8.8.8.8: icmp_req=3 ttl=46 time=13.9 ms

--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 3016ms
rtt min/avg/max/mdev = 13.910/13.926/13.951/0.010 ms

但如果我使用p.StandartInput.Write("\x3"); 停止ping,它永远不会进入statistics 部分,它挂在序列164 bytes from 8.8.8.8: icmp_req=1 ttl=46 time=13.9 ms 并且不要继续阅读,如何显示@ 987654328@ 停止ping 进程后?

换句话说,我的问题是当用户想要停止 ping 时,它应该在用于 ping 的特定时间内显示 statistics...

更新

我已经实现了p.StandartInput.Write("/x3");,它会中断 ping 过程,但它不显示统计信息,只是挂在那里。

【问题讨论】:

写一个Ctrl-C到你的std输入流,十六进制是3,所以Write("\x3") 我已经尝试在adb shell ping -c 3 8.8.8.8 中使用 CTRL+C 但它只是立即停止,它不显示统计部分... 刚试了一下,它会生成统计数据行...因为您是通过adb 进行测试的,实际上首先在adb shell 中运行shell,然后运行ping,然后运行Ctrl-C,您就是Ctrl-C/中止 adb 进程而不是 ping 进程 看来,如果您调用p.Exit()StandardOutput 也会在本地关闭。尝试在循环之前定义Exited。如果您的进程被杀死,则会引发此事件。尝试获取进程的最新输出(作为sender 传递给事件)。 adb shell,然后是ping 8.8.8.8,然后是Ctrl-C 以中止ping,并且将显示统计信息,它也适用于进程,因为我在一对夫妇中使用ping我的应用程序...... 【参考方案1】:

如果您真的对 ping 值感兴趣,为什么不直接使用 ping 类呢? https://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping(v=vs.110).aspx

【讨论】:

因为来自 android 系统的 ping 比 Mono 框架好,我之前尝试过并注意到由于 Sand Box 的原因,MONO 的往返时间更高......它不能正常工作!它在 IPStatus.TtlExpired 中有一些错误。 如果您在意 ping 的速度,为什么不编写自己的 ICMP 服务呢?在 Linux 系统上执行这种功能可能没问题,但在移动设备/Xamarin 上,我不确定这是否是您问题的正确答案。 为什么要编写自己的 ICMP 服务?我不明白你的意思。问题是如何在进程通过 std exec 启动后停止它。 我相信,停止 ping 命令是您的问题的“解决方案”,但您的问题实际上似乎是“如何测量设备与某个 IP 地址之间的 ping 时间”。如果测量往返时间实际上是您的问题,那么编写您自己的 ICMP 服务(这是 PING 使用的)将解决您的问题。 我想你不太明白我的要求。我有时间,其他一切都很好。问题不在于!

以上是关于如何从 System.Diagnostics.Process 停止进程并最终获取统计信息的主要内容,如果未能解决你的问题,请参考以下文章

如何从外部从 GitHub 加载 JavaScript 文件? [复制]

如何将数据从回收器适配器发送到片段 |如何从 recyclerview 适配器调用片段函数

如何从 Firebase 获取所有设备令牌?

如何直接从类调用从接口继承的方法?

如何从服务器获取和设置 android 中的 API(从服务器获取 int 值)?如何绑定和实现这个

如何从Mac从android studio中的fabric注销? [复制]