Search code examples
c#processadblogcat

How to stop logcat from logging and close adb programmatically?


I am writing a small C# application to collect logcat files for an app that's running on an Android device connected to the computer.

I can easily start logcat and get it to log the desired lines to a particular text file. But every command that I've tried to stop logcat from logging doesn't work.

I've tried my solutions also when running my app with admin rights.

Here is my code:

static void Main(string[] args)
    {
        string choice;
        string clearLogging = @"adb logcat -c";
        string startLogging = @"adb logcat MyApp_LoggingTag:V AndroidRuntime:E *:S > C:\logcat.txt";
        string adbDir = @"C:\Users\me\AppData\Local\Android\android-sdk\platform-tools\";


        string clearCommand = adbDir + clearLogging;
        string startLoggingCommand = adbDir + startLogging;

        ProcessStartInfo startInfo = new ProcessStartInfo("cmd.exe", "/K " + clearCommand);
        startInfo.CreateNoWindow = true;
        startInfo.UseShellExecute = false;
        startInfo.RedirectStandardInput = true;

        //Tried giving the cmd process elevated rights and then use logcat -c  - didn't work
        //startInfo.Verb = "runas";

        Process logcatRunner = Process.Start(startInfo);

        //This works!
        logcatRunner.StandardInput.WriteLine(startLoggingCommand);

        Console.WriteLine("Logging has started.");
        Console.Write("Press Enter to stop logging....");
        Console.ReadLine();

        //-c doesn't work
        //logcatRunner.StandardInput.WriteLine(clearCommand);
        //Tried killing adb via the logcatRunner process - doesn't work.
        //logcatRunner.StandardInput.WriteLine(@"taskkill -f /im ""adb.exe""");
        //Tried killing my process - doesn't work - adb is still running and logcat is still writing logs
        //logcatRunner.Kill();

        Console.WriteLine("Logging has stopped.");
        Console.Write(@"Enter any key");
        choice = Console.ReadLine();

    }

adb is still running after I close the above application.
So my question is, having started adb and logcat successfully, how do I close both of them programmatically?


Solution

  • Doing this with your approach is complicated. You create cmd process and then start another process (adb) there. To kill adb you need to send CTRL+C to cmd, but it's not that easy because of CreateNoWindow=true. I'd suggest another approach and run adb directly, redirecting its output:

    string adbPath = @"G:\Android\android-sdk\platform-tools\adb.exe";
    ProcessStartInfo startInfo = new ProcessStartInfo(adbPath, "logcat MyApp_LoggingTag:V AndroidRuntime:E *:S");
    startInfo.CreateNoWindow = true;
    startInfo.UseShellExecute = false;
    startInfo.RedirectStandardOutput = true;           
    // if you don't want to recreate it each time - choose another file mode, like FileMode.Append
    using (var fs = new FileStream(@"C:\logcat.txt", FileMode.Create, FileAccess.Write, FileShare.Read)) {
        using (var writer = new StreamWriter(fs)) {                    
            Process logcatRunner = new Process();
            logcatRunner.StartInfo = startInfo;
            logcatRunner.EnableRaisingEvents = true;
            logcatRunner.OutputDataReceived += (sender, args) => {
                // Data null indicates end of output stream - don't write it
                if (args.Data != null) {
                    writer.Write(args.Data);
                    // flush immediately if needed
                    writer.Flush();
                }
            };
            logcatRunner.Start();
            logcatRunner.BeginOutputReadLine();
            Console.WriteLine("Logging started, press any key to stop");
            Console.ReadKey();
            logcatRunner.CancelOutputRead();
            logcatRunner.Kill();
            logcatRunner.WaitForExit();
        }
    }