Skip to main content
edited tags
Link
svick
  • 24.3k
  • 4
  • 52
  • 89
added 15 characters in body; edited title
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237

C# await Await and interactive Android ADB shell

I'm writing an app to let me interact and debug my android over USB using the android SDK and the ADB command. I create a Process with redirected input and output streams and basically run "ADB shell", and I want to be able to wait for the prompt, enter commands and parse the results. Here's

Here's a sample running 'ps'ps and getting the results:

Is there something I can reliably do to keep from creating new Memory streamsMemoryStreams? For instance, like could I do an array copy on MemoryStream.GetBuffer()MemoryStream.GetBuffer() to itself and use MemoryStream.SetLength()MemoryStream.SetLength()? Is there an entirely better way to do it than using async and await?

C# await and interactive Android ADB shell

I'm writing an app to let me interact and debug my android over USB using the android SDK and the ADB command. I create a Process with redirected input and output streams and basically run "ADB shell", and I want to be able to wait for the prompt, enter commands and parse the results. Here's a sample running 'ps' and getting the results:

Is there something I can reliably do to keep from creating new Memory streams, like could I do an array copy on MemoryStream.GetBuffer() to itself and use MemoryStream.SetLength()? Is there an entirely better way to do it than using async and await?

Await and interactive Android ADB shell

I'm writing an app to let me interact and debug my android over USB using the android SDK and the ADB command. I create a Process with redirected input and output streams and basically run "ADB shell", and I want to be able to wait for the prompt, enter commands and parse the results.

Here's a sample running ps and getting the results:

Is there something I can reliably do to keep from creating new MemoryStreams? For instance, could I do an array copy on MemoryStream.GetBuffer() to itself and use MemoryStream.SetLength()? Is there an entirely better way to do it than using async and await?

Source Link

C# await and interactive Android ADB shell

I'm writing an app to let me interact and debug my android over USB using the android SDK and the ADB command. I create a Process with redirected input and output streams and basically run "ADB shell", and I want to be able to wait for the prompt, enter commands and parse the results. Here's a sample running 'ps' and getting the results:

CreateProcess("shell");
string data = await ReadToPrompt(":/ $ ");
_Process.StandardInput.WriteLine("ps");
string echo = await ReadLine(); // my command echoed back
string dataAndPrompt = await ReadToPrompt(":/ $ ");

It works (although I'm getting extra CR in the byte stream, CR/LF is coming as CR/CF/LF), but I can't help but wonder if there's a better way than what I have:

Process _Process;
MemoryStream _Remaining; // bytes left after ReadToPrompt
byte[] _Buffer = new byte[0x10000];

public async Task<string> ReadLine()
{
    return await ReadToPrompt("\r\n");
}

public async Task<string> ReadToPrompt(string prompt)
{
    MemoryStream ms = _Remaining == null ? new MemoryStream() : _Remaining;
    int promptSize = prompt.Length;
    int pos = 0;

    while (true)
    {
        // read what we can from the process's standard output
        int count = await _Process.StandardOutput.BaseStream.ReadAsync(_Buffer, 0, _Buffer.Length);
        ms.Write(_Buffer, 0, count); // write new data to memory stream

        // convert all new bytes to check for prompt
        string testString = Encoding.ASCII.GetString(ms.GetBuffer(), pos, (int)(ms.Position - pos));
        int promptPos = testString.IndexOf(prompt);
        if (promptPos > 0)
        {
            // we found it, result is up to and including prompt
            int stripLength = pos + promptPos + promptSize;
            string result = Encoding.ASCII.GetString(ms.GetBuffer(), 0, stripLength);

            // store remaining data in a MemoryStream for the next call
            _Remaining = new MemoryStream();
            _Remaining.Write(ms.GetBuffer(), stripLength, (int)(ms.Position - stripLength));
            return result.Replace("\r\r", "\r");
        }

        // we didn't find it but we know it isn't in what we got, so move first position
        // to check to the position - promptSize
        pos = (int)(ms.Position - promptSize);
        pos = (pos < 0) ? 0 : pos;
    }
}

Is there something I can reliably do to keep from creating new Memory streams, like could I do an array copy on MemoryStream.GetBuffer() to itself and use MemoryStream.SetLength()? Is there an entirely better way to do it than using async and await?