Skip to content

Instantly share code, notes, and snippets.

@ctaggart
Last active December 26, 2015 01:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ctaggart/7071437 to your computer and use it in GitHub Desktop.
Save ctaggart/7071437 to your computer and use it in GitHub Desktop.
namespace SourceLink
open System
open FSharp.Control.Observable // for GuardedAwaitObservable from FSharx.Core
type Process() =
let si = Diagnostics.ProcessStartInfo()
do
si.UseShellExecute <- false
si.WindowStyle <- Diagnostics.ProcessWindowStyle.Hidden
si.RedirectStandardOutput <- true
si.RedirectStandardError <- true
let stdout = Event<string>()
let stderr = Event<string>()
member x.FileName with set v = si.FileName <- v
member x.Arguments with set v = si.Arguments <- v
member x.WorkingDirectory with set v = si.WorkingDirectory <- v
[<CLIEvent>]
member x.Stdout = stdout.Publish
[<CLIEvent>]
member x.Stderr = stderr.Publish
member x.Run() =
use p = new Diagnostics.Process()
p.StartInfo <- si
p.OutputDataReceived |> Event.add(fun ev -> if ev.Data <> null then stdout.Trigger ev.Data)
p.ErrorDataReceived.Add(fun ev -> if ev.Data <> null then stderr.Trigger ev.Data)
p.Start() |> ignore
p.BeginOutputReadLine()
p.BeginErrorReadLine()
p.WaitForExit()
p.ExitCode
member x.AsyncRun() = async {
use p = new Diagnostics.Process()
p.StartInfo <- si
p.OutputDataReceived |> Event.add(fun ev -> if ev.Data <> null then stdout.Trigger ev.Data)
p.ErrorDataReceived.Add(fun ev -> if ev.Data <> null then stderr.Trigger ev.Data)
p.Start() |> ignore
p.BeginOutputReadLine()
p.BeginErrorReadLine()
// attaches handler to Exited event, enables raising events, then awaits event
// the event gets triggered even if process has already finished
let! _ = Async.GuardedAwaitObservable p.Exited (fun _ -> p.EnableRaisingEvents <- true)
return p.ExitCode }
member x.RunAsync() = x.AsyncRun() |> Async.StartAsTask
let p = Process(FileName="where", Arguments="msbuild")
let writeOut = printfn "%s"
p.Stdout |> Event.add writeOut
p.Stderr |> Event.add writeOut
let exitCode = p.Run()
printfn "exit code: %d" exitCode
printfn ""
let p = Process(FileName="where", Arguments="fsc")
let writeOut = printfn "%s"
use subscriptionStdOut = p.Stdout |> Observable.subscribe writeOut
use subscriptionStderr = p.Stderr |> Observable.subscribe writeOut
let exitCode = p.AsyncRun() |> Async.RunSynchronously
printfn "exit code: %d" exitCode
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment