LOGIN  |  REGISTER
Smart Living Made Brilliant!
CASTLEOS FORUM

HomeScripting

A forum for information about scripting with CastleOS. Get samples, suggestions, and other help here

IO Redirection Example Messages in this topic - RSS

Nick Bento
Nick Bento
Posts: 221


12/31/2014
Nick Bento
Nick Bento
Posts: 221
Hello All,
I figured I'd post an example of how to do IO redirection with C#. This is useful for having castleOS access output from another program. For an example, I'll discuss a program I threw together with some help from examples I found via google (many are from MSDN and dotnetperls.com, as well as stackoverflow.com. These are all excellent sources to check out for example codes, questions, and how-to's) which gives me an overview of my systems.
The forum posts I used from there to get me on the right path are the following, if you'd like to try and write a similar program:
http://stackoverflow.com/questions/262280/how-can-i-know-if-a-process-is-running
http://stackoverflow.com/questions/1393711/get-free-disk-space
http://stackoverflow.com/questions/278071/how-to-get-the-cpu-usage-in-c

Here is sample output from running the program i wrote:
Processor utilization is at 32.88%. Available system memory is 4.8 Giggabytes. Could not scan drive for storage space. Plex Media Server is not currently running.

Now what would be neat is if we have CastleOS speak this back to me when I ask "System Status" (or whatever custom command I'd like).
We can do that! We do the following:
  • Take our compiled program we wrote (SystemStatus.exe), and place it into C:\ProgramData\CastleOS\CastleOS Kinect Service\Scripts

  • Write a C# script to access it, retrieve the output of it, and then have CastleOSKinectService speak this. We also place that script into C:\ProgramData\CastleOS\CastleOS Kinect Service\Scripts. In this example we call this script SystemStatus-Interface.cs

  • Go into the Kinect Configurator, create the custom command we want recognized (in my case, it is "System status"), and assign the SystemStatus-Interface.cs script to it, then save.

I have attached the interface script I wrote, using the example from http://www.dotnetperls.com/redirectstandardoutput and modifying it a little bit to work with CastleOS. I'll give a brief overview of how it works and what's going on.


There are 4 'using' statements. Using is like an import, it tells the code what libraries to look into for commands. We use System, System.Diagnostics (which is for querying CPU/Memory status), System.IO (used to check disk space, and also related to Memory/CPU), and the CastleOSKinectService library, which is where our CastleOS API calls come from (in this case, the ScriptingAPI.Speak method).

The structure of a script for CastleOS is generally of the form public class [your_class_name], which then encompasses the public void Main(string[] args){} method, which is required for all scripts. This is what's referred to as the entry point of the script, it's the code that gets executed to get things rolling.

Within this Main method is the code that will run. The first block of code makes a call to the ScriptingAPI.Speak method, to have castleOS speak "Scanning Systems"; this is mainly to let us know that the script is running, as the call to our SystemStatus program takes a few seconds to execute and return.
We then use ProcessStartInfo to call upon our SystemStatus.exe. Note that we tell it to not use Shell Execution (it will run in the background instead of launching a new shell window), and we tell it we want to Redirect its output (this will capture the output into a variable we can read from once the program finishes).

We then launch the process. When we use the 'using' keyword in the code block, we basically create a temporary variable on the fly that we can use for other processing; once that block of code finishes executing, the variable is no longer used and is deallocated. In this case, we're creating a temporary variable of type Process called 'process', and assigning it the result of running our process we created just before this code (which we called 'start').

Within that using block, we then use what's called a StreamReader that we are calling 'reader' to read the result of the process we ran. We read the result by looking at process.StandardOutput, which is the captured output of SystemStatus.exe that we ran. Then, we tell the reader to read all that data into a string variable we call 'result'.

Now that we have the string we want to speak stored into that 'result' variable, we can have the CastleOS Speak method simply speak that string by passing it as an argument to the method:
ScriptingAPI.Speak(result);

This will have the CastleOSKinectService speak "Processor utilization is at 32.88%. Available system memory is 4.8 Giggabytes. Could not scan drive for storage space. Plex Media Server is not currently running." as in the example above.

This is a slightly more complex example of what can be done with the scripting system. If you have any questions feel free to ask! smile
edited by nikku on 12/31/2014
edited by nikku on 12/31/2014

--
-Nick B.


0 link
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3390


1/3/2015
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3390
Hey Guys, again I want to suggest you bring these types of questions to the C# forums at Microsoft and StackOverflow. This really isn't a CastleOS, or even scripting, question. What you're looking for info on is really outside the scope of CastleOS. It's not that we don't want to help, but those two forums have thousands of users daily living and breathing this. They'll be able to help far more than those here...
edited by ccicchitelli on 1/3/2015
+1 link
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3390


1/3/2015
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3390
+1 link
Nick Bento
Nick Bento
Posts: 221


1/30/2015
Nick Bento
Nick Bento
Posts: 221
Hey All,
I wrote a pair of programs that will get around the issue, and are actually pretty neat/useful in general!
It consists of a Server (CastleOSAppLaunchServer.exe) and a client (CastleOSAppLaunchClient.exe). You run the server app on whatever machine you want to have applications launch on. Then, on whatever machine you want to be able to launch voice commands to launch apps with (machine with Kinect), you place the client program on it (I would put it in the scripts folder for simplicity). Then in your custom script, you just use Process.Start to call the client app and pass it the ip address of the machine running the server, along with the name of the program you want to launch and any arguments you want to pass it. For example, I can put the following in my script to launch internet explorer and have it navigate to google.com:
Process.Start(@".\CastleOSAppLaunchClient.exe", "192.168.0.130 iexplore.exe www.google.com");

The neat thing about this is that I could launch apps on devices that aren't even running the CastleOS Kinect Service (for instance, I could have it launch internet explorer on my windows 8.1 tablet and have it navigate to the CastleOS Portal for my system by saying "Jarvis, Bring up the control interface") smile

Also of note, if you wanted the server program to automatically run when the system starts, it would have to be added to the startup programs for the user that logs into the system, it can't be used as a service (otherwise we'd just be right back to our original problem haha!)

Try them out and let me know if it helps, thanks!

Also this was a quick buildout, I plan to recode the server portion to run in the system tray instead of a console window, but figured for now I'd post this version for people to try out and report any issues smile

EDIT: I'm rewriting/renaming parts of the app as I found a bug, and also realised I probably shouldn't use the CastleOS name in it, particularly without expressed permission wink
edited by nikku on 1/30/2015
edited by nikku on 1/30/2015
edited by nikku on 1/30/2015

--
-Nick B.
+1 link
Nick Bento
Nick Bento
Posts: 221


1/30/2015
Nick Bento
Nick Bento
Posts: 221
No Problem. I found a bug in that version though so I removed it. I'm gonna upload a better version later on that will be much better smile
I'll edit my original post once it's ready.
edited by nikku on 1/30/2015

--
-Nick B.
+1 link
Nick Bento
Nick Bento
Posts: 221


1/30/2015
Nick Bento
Nick Bento
Posts: 221
This is an update of my original post with the new Application and fixes. The server now runs in the system tray instead of a console window smile

Hey All,
I wrote a pair of programs that will get around the issue, and are actually pretty neat/useful in general!
It consists of a Server (RemoteAppLaunchServer.exe inside the RemoteAppLaunchServer folder) and a client (RemoteAppLaunchClient.exe). You place the RemoteAppLaunchServer folder (which includes the executable as well as assistance files it needs to run) on whatever machine you want to have applications launch on and execute the exe. This will launch an application that shows up in your system tray. If you click the little icon (it looks like a computer), it has a Console you can look at to make sure things are working. Then, on whatever machine you want to be able to launch voice commands to launch apps with (machine with Kinect), you place the client program on it (I would put it in the scripts folder for simplicity). Then in your custom script, you just use Process.Start to call the client app and pass it the ip address of the machine running the server, along with the name of the program you want to launch and any arguments you want to pass it. For example, I can put the following in my script to launch internet explorer and have it navigate to google.com:
Process.Start(@".\RemoteAppLaunchClient.exe", "192.168.0.130 iexplore.exe www.google.com");

The neat thing about this is that I could launch apps on devices that aren't even running the CastleOS Kinect Service (for instance, I could have it launch internet explorer on my windows 8.1 tablet and have it navigate to the CastleOS Portal for my system by saying "Jarvis, Bring up the control interface")

Also of note, if you wanted the server program to automatically run when the system starts, it would have to be added to the startup programs for the user that logs into the system, it can't be used as a service (otherwise we'd just be right back to our original problem haha!)

Try them out and let me know if it helps, thanks!

Also this was a quick buildout, I plan to recode the server portion to run in the system tray instead of a console window, but figured for now I'd post this version for people to try out and report any issues

--
-Nick B.


Attachments:
RemoteAppLaunch.zip
+1 link