Using the System.Diagnostics Classes in the .NET Compact Framework

                   Part I
                   Sub Topics: Spawning Processes,   Viewing Processes
                                       Performance Counters, Stack Trace, and Stack Frame Classes

I recently put together a small .NET CF application to demonstrate menuing and launching tasks from a CE device with no touch screen. 
One of the requirements was the ability to transfer data to and from the device via an FTP application. File Transfer Protocol is something
not native to the CE/Mobile footprint and must be purchased separately from software vendors. So a method of integrating an application
to the FTP process was needed.

Spawning Processes

The first task was to create some sort of menuing system and also have the Compact Framework program launch third party applications.
One could quickly build a text file in XML or ASCII NVPs (name value pairs) which contains a menu item and then the process file to
launch for example:

     "File Upload", "ftp.exe -s file.txt"
     "File Retrieve", "ftp.exe -r file.txt"
     "Exit", "exit"

The System.Diagnostics class provides the function to launch programs including arguments. See the following example:

                         
                         // Code to open file and parse menu items pair done on application initialization
                         // Application uses direction keys for menu item selection on a touch less device
                         // when we know which item we want and the user presses "SELECT" then

                          Systems.Diagnostics.Process.Start("exe file name", "arg1 arg2 arg3");

 

Sure enough, this works and spawns the application. Interestingly enough it makes the launched application appear in the foreground with
the Compact Framework app now in the background.  There is another signature for this "exec" function:

     Systems.Diagnostics.Process.Start(ProcessStartInfo)
 
The PSI class can be used as an argument to this function in order to specify different startup parameters for example:

using System.Diagnostics;

                          ProcessStartInfo psi = new ProcessStartInfo("app.exe"); 
                          psi.WorkingDirectory  = "\\somepath\\path"; 
                          psi.Arguments = "arg1 arg2 arg3";
                          Process.Start(psi);

Note: the full framework lets you specify some additional items such as window style i.e. launch minimized, hidden etc. There is also an
additional boolean argument which lets you specify whether or not the shell launches the application. For the shell to launch the app you
would set "psi.UseShellExecute = true;"

 

Listing Processes

You can use the static class Process.GetProcesses to obtain a list of the current win32 processes running. This following example illustrates
how to fetch a list of them. The optional argument allows one to specify this name of a remote machine.

using System.Diagnostics;

                         // local machine
                         Process [] listlocal = Process.GetProcesses();
                         // remote machine
                         Process [] listremote = Process.GetProcesses("remoteComputer"); 

 

Note: this functionality does not exist for the compact framework. To obtain information on running processes use platform invoke to
call the unmanaged functions. Or alternatively you can fetch information on the current running process by calling  Process.GetCurrentProcess()
which will allocate an object and associate it with the active process.  If you know the ID of the process you can obtain information via
the call Process.GetProcessById(). 


Listing Modules Loaded by a Process

You can use the ProcessModule and ProcessModuleCollection to iterate through a list of modules which an application has loaded.
These classes can be used to obtain the following information:

           ModuleName
           BaseAddress
           EntryPointAddress
           FileName

There is one of the above records for each module loaded, additionally there is one entry of the MainModule as well.

Note: this functionality does not exist for the compact framework. To obtain information on running processes use platform invoke to
call the unmanaged functions.

 

Performance Counters

There are many of these :

          PerformanceCounter                           Represents a performance counter component
          PerformanceCounterCategory            Represents a performance counter category
          CounterCreationData                          Represents a performance counter installer
          CounterCreationDataCollection         Represents a performance counter collection

These are used as general classes to collect statistics on operations. For example you would first set up a categories via the
CounterCreationDataCollection(), CounterCreationData() and the PerformanceCounterCategory() classes.

You would then create the performance counters by calling PerformanceCounter() for each type of category you created perviously.
Finally perform your run time processing by walking thur your data and by calling PerformanceCounter.Increment() or
PerformanceCounter.IncrementBy(n) based on the hit corresponding to each counter.

In summary these are nice classes to assist in data collection for example, network statistics, hardware faults etc.

Note: this functionality does not exist for the compact framework.


 

StackTrace Class

Represents a class which is an ordered collection of one or more stack frames. Used with debug builds one can iterate through the
StackTrace class frames to obtain diagnostic and debugging information. StackTrace has a FrameCount field member which can be used
to iterate through StackFrames once captured via exceptions.

using System.Diagnostics;

                         // for (i = 0: i < StackTrace.FrameCount; i++)
                                 {
                                  StackFrame sf = st.GetFrame(i);
                                  // print out trace data
                                  }

Note: this functionality does not exist for the compact framework but TraceListeners and other Debug classes do.

 

StackFrame Class

Provides information about a StackFrame, which represents a function call on the call stack for the current thread. The various field
members provide information on debugging information such as:

          GetFileColumnNumber()          Returns the column number of where the event occurred in the source code
          GetFileLineNumber()               Returns the line number of where the event occurred in the source code
          GetFileName()                         Returns the module name where the even occurred in the source code
          GetFileColumnNumber()          Returns the column number of where the event occurred in the source code
          GetLOffSet()                           Returns the Line offset from the start of the MSIL code module where the event occurred
          GetMethod()                           Returns the method name where the event occurred
          GetNativeOffset()                    Returns the offset from the start of the JIT code where the event occurred
          
Note: this functionality does not exist for the Compact Framework but TraceListeners and other Debug classes do.

As you can see only a subset of the 2.0 Framework is provided in the Compact Framework. For Win32 functionality work arounds typically
call unmanaged code via platform invoke. There is a separate and complete Exception Handler interface provided to catch, handle and
throw real time exceptions provided for the native C as well as C++ models. See the following page for links to four separate topics. You can
capture processor specific information this way. Most of the time this is not needed, but for hard core real time applications it may.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcepbguide5/html/wce50oriExceptionHandlingForWindowsCECompilers.asp



              Using the System.Diagnostics Classes in the .NET Compact Framework                                            Device Programming                                          

                               

Feedback/Contact  paulzazzarino@3zwireless.com .

Copyright 2006 3zwireless Ltd, This page last updated on 04/2006