Hacker News new | past | comments | ask | show | jobs | submit login
Cmd - A saner way to running external programs from C# (github.com/manojlds)
28 points by manojlds on Dec 8, 2012 | hide | past | favorite | 11 comments



This is a neat use of dynamic/reflection. But why is it "saner"? What's wrong with wrapping the normal process I/O stuff and just doing: cmd("git clone") ?

This is the same question I have when I see dynamic typing used to access data sources. Like reading a CSV file and doing 'row.Field1' instead of 'row["Field1"]'.

Is there really any benefit or point, other than being a cute hack?


Yes, it started out as a hack. I wanted to see how close I can get to the Python implementation. I am not envisioning it to be used, but would be happy if someone found it useful :)


Nice idea. A few problems spring to mind:

* Doing the following will hang if the stdout buffer fills up:

    var output = process.StandardOutput.ReadToEnd();
    process.WaitForExit();
Take a look at Kudu (Azure's Git publishing platform) for the way they do it: https://github.com/projectkudu/kudu/blob/master/Kudu.Core/In...

* You need to expose a way to capture `StandardError`.


It won't hang as long as you're redirecting only standard output. If you want to read both StandardOutput and StandardError, you need to do it from separate threads: either with explicit BeginInvoke/EndInvoke calls as in Kudu, or more simply, by listening on the OutputDataReceived/ErrorDataReceived events then calling BeginOutputReadLine/BeginErrorReadLine.

(The reason for this is that the two streams are redirected to separate pipes, each of which has its own fixed-size buffer. If you forget to read from one pipe while you read from the other, its buffer fills up, and the writer - the program being executed - blocks. With standard error redirection turned off, the program writes directly to the console, which is safe.)


Yes, I have so for been working on getting the Base API right. Will be adding background process, stderr redirect etc. Thanks for the input.


This looks quite awesome overall. I do wonder, though, why you can't do the actual invokation in Cmd.TryInvokeMember rather than Cmd.TryInvoke? That'll get rid of the () at the end of commands, from my quick read.


I was thinking the same. I wanted to support cmd.git(git_dir : blah).branch(a: true) kind of scenarios however. Think I would just not go with it if it means removing the extra (). Thanks


Yeah, I think skipping the extra () is worth giving that up. Plus, you could do this in most cases: cmd.git.branch(a: true, git_dir: blah)


The ugly () are now gone. :)


This won't work for one very simple reason: Windows apps, unlike their *nix counterparts, do not have a unified command line switch format. This will only really be useful for standard getopt(long) implementations, which is a very small portion of the software available on Windows.


Very valid point. I am working on the powershell equivalent for this, and I would be happy to support only powershell commands and standard getopt commands.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: