Piping processes, VSLab Shell foundations

by cisterni 16. September 2008 09:40

VSLab provides the foundations for using Visual Studio as an interactive environment, a sort of big environment for Domain Specific Languages in which you can issue commands interactively to control virtually anything. Now that this foundation is in place we are working to provide the set of packages that shows this potential and transform VSLab into something that is usable for people, not only by F# programmers. Of course this is also a way to find the right abstractions you need when developing packages so that we can possibly extend the core to support new functionalities.

One of the coolest packages I'm working on is the VSLab Shell package, a mean to turn VS into next generation interactive shell, in which text and GUI mix together to obtain a new environment in which point-and-click is used in conjunction with text-based scripts to get the best from the two environments. We are currently defining the core operations of a traditional shell, such as process management and piping, and I want to share with you a neat piece of code we wrote this night to express process piping using F# and F# interactive. Here is the code:

open System.Diagnostics

open System.IO

let pwd = Directory.GetCurrentDirectory

let createProcess exec args =

  let pi = new ProcessStartInfo()

  pi.Arguments <- args

  pi.CreateNoWindow <- false

  pi.RedirectStandardInput <- true

  pi.RedirectStandardError <- true

  pi.RedirectStandardOutput <- true

  pi.UseShellExecute <- false

  pi.WorkingDirectory <- pwd()

  pi.FileName <- exec

  let p = new Process()

  p.StartInfo <- pi  p

let (^>) (out:Process) (pf: bool -> string -> unit) =

  out.ErrorDataReceived.Add(fun d -> pf false d.Data)

  out.OutputDataReceived.Add(fun d -> pf true d.Data)





let (^|) (inp:Process) (out:Process) =

  inp.EnableRaisingEvents <- true

  inp.ErrorDataReceived.Add(fun d -> out.StandardInput.WriteLine d.Data)

  inp.OutputDataReceived.Add(fun d -> out.StandardInput.WriteLine d.Data)

  inp.Exited.Add(fun _ -> out.StandardInput.Close())





let p = createProcess @"c:\Windows\System32\Robocopy.exe" "/?"

let s = createProcess @"c:\Windows\System32\sort.exe" ""

let q = createProcess @"c:\Windows\System32\sort.exe" "/R"

p ^| q ^| s ^> (fun out d -> printfn "%s: %s" (if out then "out" else "err") d)


This code shows a limit of .NET API, we have to coordinate the piping process explicitly because we cannot specify the handle to the streams in the ProcessStartInfo structure (in Win32 would be possible). We define two overloaded operators using the ^ prefix to have right association. The callbacks provided by the Process class allow to avoid polling of streams. This code has requested an amount of spelunking of System.IO namespace, I was surprised to find that using the general Stream class it is not possible to multiplex IO operations as the select system call would have permitted. Some day I will post considerations about this design that at a first sight may seem weird but after some thoughts I decided that is reasonable though far from elegant.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

General | Shell

VSLab Shell

by cisterni 27. July 2008 17:26

I think that one of the most interesting areas of VSLab, partly unforeseen, is the project of developing a next generation system shell as a package. System shells have a long history and there is always an attempt to find the new one, but I think these are here to stay, but they also are the past. We are living in a world where the stream-based composition of software is far from satisfactory, and also the completion forms provided by shells are inadequate.

In 2001 I defined a shell called ObjShell, attempting to exploit the component-based nature of COM for software composition. At that time I realized that Unix shells are just a simpler version of this where each program was a component with a well defined interface and an associated process, and the shell was the mean by which these components were integrated. ObjShell were a very nice project and today I can say it's a pity I didn't find the time to work on it for the .NET version, otherwise the Power Shell would have arrived several years before. And in fact I was contacted by the PS team (I spoke to Jeffrey Snover when He was in charge of PS) though I didn't succeded in trying to convince on some basic design principles of the ObjShell that I would have loved to see in the PS. I'm not a PS fan, I like the object streaming metaphor, but I didn't feel need for another unreadable language full of switches and dollars.

I think that programming languages and the associated toolchain have grown enough to blur the distinction between the program and the shell, it was true for VB and COM and it is more true nowadays with .NET and languages such as F# using the interactive top level. Now with few lines you can read system counters as PerfMon does and do several other things. VSLab Shell will be a package designed to be next generation shell, where statements are highlighted to be executed and a single file may contain several scripts. Intellisense it is far better than Tab-based completion. At the moment we are working on the core functionalities of the shell, but also designing interfaces to hardware such as ILO featured by HP.

More about VSLab Shell will be available in the next release of VSLab.

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

Design | Shell

Powered by BlogEngine.NET
Theme by Mads Kristensen

VSLab blog

VSLab is a Visual Studio extension designed to support Visual Studio interaction from F# interactive. It is a Microsoft product developed at University of Pisa, by a team lead by Antonio Cisternino.


Recent comments

Comment RSS


The opinions expressed herein are my own personal opinions and do not represent my employer's view in  anyway.

© Copyright 2008