6 ms·
Cmd - A saner way to running external programs from C#
- ComputerGuru 14y agoThis 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.
- manojlds 14y agoVery 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.
- duncans 14y agoNice 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/Infrastructure/Executable.cs https://github.com/projectkudu/kudu/blob/master/Kudu.Core/In... * You need to expose a way to capture `StandardError`.
- timrobinson 14y agoIt 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.)
- manojlds 14y agoYes, I have so for been working on getting the Base API right. Will be adding background process, stderr redirect etc. Thanks for the input.
- daeken 14y agoThis 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.
- manojlds 14y agoI 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
- MichaelGG 14y agoThis 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?
- manojlds 14y agoYes, 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 :)
- visualcsharp 14y agoI don't understand this. Why is it necessary to pretend that running command-line programs is like accessing objects? Why is " git clone https://blah https://blah " somehow not sufficient? Why is it necessary to present that as chained object calls? How is this "saner?"