16.6. The .NET interface to SensorShell

To simplify the development of sensors for Microsoft Windows tools such as Office or Visual Studio, we have developed an example SensorShell "wrapper" package using C# and the .NET 2.0 environment. This package is available in the Hackystat server download directory as DotNetSensorShellWrapper.zip.

[Note]Note

If the above link does not work, it is likely that you are accessing this documentation from the Hackystat Developers Services website. To obtain a working link, please access this documentation from the Help page of an installed Hackystat server, such as the one at the Hackystat Developer Services Server.

The .NET wrapper for SensorShell works by invoking the interactive interface to SensorShell as a subprocess, and passing strings to it to invoke the various commands. A more efficient alternative, of course, would be to implement a "native" SensorShell in C#, but before embarking on that process, you may wish to review the set of requirements for SensorShell listed at the beginning of this chapter, and decide whether the additional implementation and maintenance burden is worth the benefit of improved performance.

Example 16.5, “.NET wrapper code directory structure” illustrates the directory structure obtained after downloading and unzipping this package.

Example 16.5. .NET wrapper code directory structure

DotNetSensorShellWrapper/
                         Readme.txt
                         Hackystat.SensorShell.dll
                         Demo.exe
                         sensorshell.jar
                         SensorShellWrapper.sln
                         SensorShellWrapper.suo
                         Demo/
                              Demo.csproj
                              Demo.csproj.user
                              Program.cs
                         SensorShell/
                                     AssemblyInfo.cs
                                     JavaUtil.cs
                                     SensorShell.cs
                                     SensorShell.csproj
                                     SensorShell.snk
                                     SensorShellException.cs
                                     SensorShellProperties.cs

The package provides source for two components: the actual SensorShell wrapper (in the SensorShell directory) and a demo program that invokes the SensorShell wrapper and sends it an example command (in the Demo directory). The top-level directory contains a ReadMe file with additional information, the .dll file generated by building the Sensorshell wrapper, the Demo executable, a copy of the SensorShell jar file that is invoked as the subprocess, and the .suo and .sln project files for this package.

To provide some idea of how this wrapper works, Example 16.6, “Demo code showing use of the .NET SensorShell wrapper” shows the source code for the Demo program.

Example 16.6. Demo code showing use of the .NET SensorShell wrapper

using System;
using System.Collections.Generic;
using System.Text;

using Hackystat.SensorShell;

namespace Demo
{
    public class Program
    {
        public static void Main(string[] args)
        {
            if (args.Length != 3)
            {
                printUsage();
                return;
            }

            try
            {
                string javaHome = args[0];
                string sensorShellJarFilePath = args[1];
                string commandToSensorShell = args[2];

                Console.Out.WriteLine("Using Java Home = " + javaHome);
                Console.Out.WriteLine("Using sensorshell.jar = " + sensorShellJarFilePath);
                Console.Out.WriteLine("Using CommandToSensorshell = " + commandToSensorShell);
                Console.Out.WriteLine();

                //Create .Net SensorShell wrapper instance.
                SensorShell shell = new SensorShell("DemoSensor", javaHome, sensorShellJarFilePath);

                //Always call start to start the java sensorshell subprocess.
                shell.Start();

                //Connects to delegates to be notified for specific event.
                //Delegate is like Java listener, they are call-back functions.
                //The main difference is that delegate methods are called using thread-pool threads
                //(i.e. Don't make the assumption they are called in the main thread!).
                //Connecting to delegates is NOT required, but they can be used to provide feedback
                //to user.
                shell.CommandInput += new SensorShellMessageDelegate(OnStdinMessage);
                shell.StdoutOutput += new SensorShellMessageDelegate(OnStdoutMessage);
                shell.StderrOutput += new SensorShellMessageDelegate(OnStderrMessage);

                //Pass whatever command string to the java subprocess.
                //Note that this .net method does not check command validity, nor does it tell you
                //whether the command is executed by the Java sensorshell successfully or not.
                //If you want to know that, you have to connect to StdoutOutput and StderrOutput.
                shell.DoCommand(commandToSensorShell);

                //Quit
                shell.Quit(0);
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine("An exception occurred: " + ex.Message);
                Console.Error.WriteLine(ex.StackTrace);
            }
        }

        //Note: This is whatever the Java SensorShell sends to stdout.
        //      This methd is called in a separate thread-pool thread, so the sequence of the output
        //      you can from the console may not be as expected.
        private static void OnStdoutMessage(string msg)
        {
            Console.Out.WriteLine("[Java SensorShell Output] " + msg);
        }

        //Note: This is whatever the Java SensorShell sends to stderr.
        //      This methd is called in a separate thread-pool thread, so the sequence of the output
        //      you can from the console may not be as expected.
        private static void OnStderrMessage(string msg)
        {
            Console.Out.WriteLine("[Java SensorShell Error] " + msg);
        }

        //Note: This is just an echo to whatever you send to the Java Sensorshell using 
        //      DoCommand(string cmd).
        private static void OnStdinMessage(string msg)
        {
            Console.Out.WriteLine("[Java SensorShell Input] " + msg);
        }

        private static void printUsage()
        {
            Console.Out.WriteLine("Usage: Demo JavaHome SensorShellJarFilePath CommandToSensorShell");
        }
    }
}

To use this wrapper for your own sensor development, you only need the Hackystat.SensorShell.dll file. You should acquire the latest version of sensorshell.jar from the Hackystat server when your tool is downloaded, and of course include your own .NET code to implement your sensor. The remainder of this package is useful to help you understand how the code was developed.