Run Target Control Command Programatically
Today I am going to talk about how to automate the opertaion of running target control command and retrieveing its output. This blogs assumes that you have downloaded an image to a device and it has booted up completely.Please look at my earlier post if you want information in this regard.The previous post will also give you information about how to create a Visual Studio Addin too if you want to create an addin for this sample.
References required for this sample:
- System.Windows.Forms
- Interop.Microsoft.PlatformBuilder.Diagnostiocs(found in C:\Program Files\Microsoft Platform Builder\6.00\cepb\IdeVS on my machine)
Using this sample code you can run any target control command like "gi proc", "s" etc and collect the output returned by the command. In order to know when the target control command has finished running we must register a shell command complete event handler. To run the command we must get the Ce Shell object from the Platform Builder debugger Object model. The following code does that.
// Get the debugger object model
CCeSystemDiagnostics diagnostics = CCeSystemDiagnostics)dte.GetObject("Yamazaki-OM");
//Initialize variable for debugger OM Model run state control
csdRunStateControl runControl = (csdRunStateControl)diagnostics.GetRunStateControl();
// Add an event handler
diagnostics.ShellCommandComplete += new csdEvents_ShellCommandCompleteEventHandler(OnShellCommandComplete);
//Initialize variable for debugger shell
csdCeShell CeShell = (csdCeShell)diagnostics.GetCeShell();
//Run target contol command
CeShell.RunCommand(Command);
I have created a function called OnShellCommandComplete which gets exceuted when the target control command completes. This method just sets a global variable called targetControlCommandCompleted to true.Here is the code for this purpose.
/// <summary>
/// A value indicating if the Target Control command completed
/// </summary>
private static bool targetControlCommandCompleted = false;/// <summary>
/// The method that handle the Target Control command completion event
/// </summary>
private static void OnShellCommandComplete()
{
targetControlCommandCompleted = true;
}
Once, the command completes, I have used the GetLastLineNumber() and GetTextOutput(int count) API's provided by csdCeShell to collect output. Here is the complete function. You can call this function once you are sure that the image has booted up completely.
/// <summary>
/// Run a given Target Control Command
/// </summary>
/// <param name="CommandName">The Target control command to be run</param>
/// <param name="waitforCommandCompletion"> Set it to true if you want to wait for the command to complete before you return back</param>
public static void RunCommand(string Command, bool waitForCommandCompletion)
{
// Get the debugger object model
CCeSystemDiagnostics diagnostics = (CCeSystemDiagnostics)dte.GetObject("Yamazaki-OM");
//Initialize variable for debugger OM Model run state control
csdRunStateControl runControl = (csdRunStateControl)diagnostics.GetRunStateControl();
// Add an event handler
diagnostics.ShellCommandComplete += new csdEvents_ShellCommandCompleteEventHandler(OnShellCommandComplete);
//Initialize variable for debugger shell
csdCeShell CeShell = (csdCeShell)diagnostics.GetCeShell();
//Run target contol command
CeShell.RunCommand(Command);
int retries = 10;
string message = "";
if (waitForCommandCompletion)
{
// We should get the completion callback within 10 seconds or so.
do
{
//Wait for PB to respond
System.Threading.Thread.Sleep(1000);
} while (targetControlCommandCompleted == false && --retries != 0);
// If no callback yet, declare an error.
if (targetControlCommandCompleted == false)
{
MessageBox.Show("ERROR: Never saw " + Command + " completion callback.", Caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
try
{
//Get the total no of lines returned as an output of the command
int TotalNoOfLines = CeShell.GetLastLineNumber();
//Iterate through each one of them
for (int count = 1; count <= TotalNoOfLines; count++)
{
//Get each line and append it to the message string
string Line = CeShell.GetTextOutput(count);
message += Line + "\n";
}
//If the comand has no output when it returns
if(message.Length == 0)
message = "The Command did not return any output message";
MessageBox.Show(message, Caption, MessageBoxButtons.OK);
}
catch (Exception e)
{
MessageBox.Show(e.Message, Caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
Note: There are some target control commands like "run BatchFileName" which do not return till the batchfile has run completely. For running these commands, you should set the waitForCommandCompletion variable to false so that you don't have to wait till the batch file has completed.