[Android Software Development] IceDragon59:
I've been using your library to create a simple GUI program in Visual Basic, and have been having pretty good luck with everything so far, and I appreciate all the hard work you've put into it. I do my best when coding to handle all possible scenarios, thereby avoiding potential bugs, and so far I had gotten rid of all but one that I have found. I couldn't find anyone posting about this in this thread or elsewhere regarding this library, so I thought I would post my findings here.

When manually issuing an ADB command with a misspelling or completely incorrect command, it infinitely hangs. Example with "get-serialno" command without the hyphen:

Return Adb.ExecuteAdbCommand(Adb.FormAdbCommand(device, "getserialno", ""))

While debugging, I step into the process and follow it to the process start in RunProcessReturnOutput method. The process starts, but never exits. If you run the same command from the command prompt, it simply brings up the same as the "/?" argument would normally bring.

If I run the same command, but with getting the exit code, i.e.,

Return Adb.ExecuteAdbCommandReturnExitCode(Adb.FormAdbCommand(device, "getserialno", ""))

I get the exit code 1, meaning the command failed, but the process successfully exited. I don't mind getting an exit code back for commands that error out if I can get back the output for successful commands.

The source of the problem I deduced was that redirecting the stdout and stderr was causing the failed command to fail to output correctly, from a full buffer or something else. After extensive Google searching, I came upon an answer posted on Stack Overflow for someone having a similar problem to me, and decided to check out the answer posted as the solution. With minor modifications, such as importing System.Threading, but mostly to suit returning the outputs (and complete disregard for the forceRegular boolean value), lo and behold, it solved my problem! And to make it better, it even significantly improved formatting of "shell ls" commands. I wanted to share this here in the event that anyone else comes across the same problem, or, if you, regaw_leinad, would like to implement it into your library.

internal static string RunProcessReturnOutput(string executable, string arguments, bool forceRegular)
{
using (Process process = new Process())
{
process.StartInfo.FileName = executable;
process.StartInfo.Arguments = arguments;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;

StringBuilder output = new StringBuilder();
StringBuilder error = new StringBuilder();

using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false))
using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false))
{
process.OutputDataReceived += (sender, e) =>
{
if (e.Data == null)
{
outputWaitHandle.Set();
}
else
{
output.AppendLine(e.Data);
}
};
process.ErrorDataReceived += (sender, e) =>
{
if (e.Data == null)
{
errorWaitHandle.Set();
}
else
{
error.AppendLine(e.Data);
}
};

process.Start();

process.BeginOutputReadLine();
process.BeginErrorReadLine();

int timeout = 500;
if (process.WaitForExit(timeout) &&
outputWaitHandle.WaitOne(timeout) &&
errorWaitHandle.WaitOne(timeout))
{
// Process completed. Check process.ExitCode here.
}
else
{
// Timed out.
}
}
string strReturn = "";
if (output.ToString().Trim().Length > 0)
strReturn = output.ToString().Trim();
if (error.ToString().Trim().Length > 0)
strReturn += error.ToString().Trim();

return strReturn;
}
}

All credit goes to Mark Byers on Stack Overflow for the solution, and to you, regaw_leinad, for making a very useful library which has helped so many people. Thank you!

In the event that you have a more elegant solution, or it's already accounted for in the library and I'm just blind, I would love to hear back from you.