Pure C# cmdlet of "less"

Sep 7, 2007 at 8:08 PM
Just a short notice, I am currently writing a PS cmdlet that will work like "less", only better. It will support streaming objects in, will support script blocks to display, and all "files" supported by PowerShell.

It is just that I want to add a few more features and test it a bit more before I add it to the patches section.

If anyone else works on a similar thing, please get in touch so we can coordinate our work - <powershellcx dot mihi42 at safersignup dot com> - thank you

In fact it will be two cmdlets, scroll-text (which is just like less) and scroll-table (which is a mix of format-table and less, which allows resizing columns and stuff dynamically).

What do you think about it?

Sep 9, 2007 at 11:17 PM
I like the concept but really don't like the name. I think of "scroll" as something the user does. You might consider something like Out-Pager. Come to think of it, the PowerShell should have probably made the Out-Host -paging parameter an extension mechanism like TabExpansion. Less is really pretty slick but I do not like the fact that it doesn't do anything until it gets all input.
Sep 10, 2007 at 12:21 AM
and i don't like those "out-" names. First, out is not a verb but a preposition, and out-host does not "out" the "host", but outputs something on the host. And in fact, the user scrolls, yes. but let-user-scroll-text is too long and contains two nouns and two verbs :)

Of course I can live with something like out-pager (i can alias it back g), but how to do the distinction between text and table (showing properties of the objects like format-table)?

In fact, it is not less' fault: less perfectly displays partial input, it is just that piping stuff into "legacy" applications will first pipe all the stuff and then run the application (like it was in good old DOS time).

Sep 10, 2007 at 9:42 PM
anyway, patch is uploaded to the patches section. feel free to use it or not.
Sep 12, 2007 at 11:16 PM
Thank you Mihi!
Sep 13, 2007 at 5:49 PM
Edited Sep 13, 2007 at 6:05 PM
I haven't had a chance to look at the code for this, but there's a lot of patches from mihi, no? Shouldn't someone be trying to convince him to join the team officially? He's already contributed more than I have ;-)


While I also squirm at the shortening of the verb form "Output To" as a preposition, it's hardly alone, since in the PowerShell universe apparently "New" and "Where" have apparently been coopted as well, and I think we're much better off sticking to the official verb list from their "CLI" spec than making up our own.

(without having tried them yet, even though I'm excited about getting rid of the annoying 'less') ...

Besides, anything that writes output to the host "Scroll"s the window, this cmdlet should actually be called "pager" or something -- it actually (appears) to be preventing scrolling, not causing it ;) (ahem).

How about Write-Paged and Write-PagedTable or even Group-Output and Group-Table?

You know ... that reminds me ... what would be really cool ... is a Start-Paging cmdlet which would turn on paged output as the default, and be paired with a Stop-Paging ... but anyway.
Sep 13, 2007 at 7:34 PM
Edited Sep 13, 2007 at 7:39 PM
about joining the team:
1) That three patches was all I had lying around here, most likely no more will follow in the near future
2) That patches are not new stuff, they have been published somewhere (where nobody found them) before; just tweaked them a bit to work inside PSCX because I guess more people will use them if they are included here. I even posted parts of my scroll-table in a discussion with some Microsoft blogger (dont remember the name) about how to parse the format-{text|table|wide} output, but did not receive any help there (had to figure it out myself...).
3) I don't mind being part of lots of development teams, but that does not mean I will take care more about the project. Most projects I contribute to are great but miss a few small things to make them "perfect" for me. You may have a look at http://sf.net/users/schierlm (and do some digging for how long I contributed to each of them if you like). And not all projects are hosted at sf.net (like this one :-) ). So you will only see the tip of the iceberg here. ESPECIALLY: I don't like it to be asked to join the devel team if all other members try to leave it as soon as I joined, just so that I have to do all the dirty work like preparing releases. (Anyway that is the main reason why i don't put all my powershell stuff into a separate project but try to contribute it here.=

About the name:
Pager means for me that you can only move the text in pages, but "less" can do much more (like searching or scrolling line-wise). But I don't know any better name, either - and unfortunately "less" is not a verb.

Sep 14, 2007 at 3:22 PM
I'll take a look on the less alternative and try to integrate it with pscx, if nobody else is working on that.

WRT Active Accessibility, there is a new managed UIAutomation library in .NET 3.0, which supports both WPF applications and the old Active Accessibility. What do you guys think of taking a dependency on .NET 3.0?
Sep 15, 2007 at 5:06 PM
That would be great Jachym. I'm pretty happy with Less but it does have a lot more functionality than I personally need. I also wish that we didn't have to wait for all output to be generated before you can start viewing/paging the output.
Sep 16, 2007 at 1:04 AM
Regarding .Net 3.0, my 2¢ is that .Net 3.0 is the gold standard of .Net Frameworks -- it is (so far) the only one to have shipped on any OS (discounting Mono releases on Linux distros, of course). I sort-of assume that in the PowerShell 2.0 time frame PowerShell itself will take a dependency on it for that reason, and so it doesn't seem unreasonable for us to do so, even if we're ahead of the curve. That said -- until and unless they do, it does add a level of complexity to the decision to use PSCX in production environments.

Also: if we do so, we will have to make darn sure that the installer uses the bootstrapper to install .Net 3.0 if it's not present.
Sep 16, 2007 at 3:31 AM
Have to disagree with ya on this one. There are several groups internal to my company that would have a problem with PSCX taking a dependency on .NET 3.0. I'd rather stick with "PSCX requires no more than PowerShell 1.0 requires". That is a much easier sell.
Sep 17, 2007 at 5:55 PM
I have checked in the first, somehow working, prototype of the Test-Scroll cmdlet, which uses my "HostUI" library.
I'd prefer to stick with the Out "verb", but what shall be the noun?

It does not support yet all of the original features (actually, none of them), but it does have one of it's own: initially, it keeps scrolling down, as the input is coming. However, once you press a key (ie. UpArrow), it stops outputting new lines, and lets you explore the existing output. If you scroll back to the last available line, it should resume scrolling. Try it out! :-)

Oisin, BTW, would you look at the HostUI code and tell me what you think?
Sep 19, 2007 at 8:10 PM
It should support more files now, so please try it out if you will:

test-scroll c:\windows\*.log 
dir c:\windows\system32 | test-scroll
Sep 19, 2007 at 9:39 PM

Oisin, BTW, would you look at the HostUI code and tell me what you think?

Sure Jachym, no problem. I'm sure it's damn good, as is the usual from yerself. I'm tied up this evening, but I'll give it a look over tomorrow.

Sep 19, 2007 at 9:59 PM
Edited Sep 19, 2007 at 10:23 PM
Here's a quick one:

      protected override void ProcessPath(PscxPathInfo pscxPath)
           using (ConsoleControl.EnterUIScope(_control, Host.UI))
               if (typeof(FileSystemProvider) == pscxPath.Provider.ImplementingType)
               //if (typeof(IContentCmdletProvider).IsAssignableFrom(pscxPath.Provider.ImplementingType))
               //    Collection<IContentReader> readers = InvokeProvider.Content.GetReader(pscxPath.ToString());
               //    if (readers != null && readers.Count > 0)
               //    {
               //        readers[0].Read(0)
               //    }
           throw PscxException.NotImplementedYet("Only the FileSystem provider is supported at the moment, sorry.");
You can remove the FileSystemProvider check and just decorate the cmdlet with:

    [Cmdlet("Test", "Scroll", DefaultParameterSetName = ParameterSetPath)]
    public sealed class TestScrollCmdlet : PscxInputObjectPathCommandBase

and when you get the ContentReader bits working, change the constraint to [ProviderConstraint(typeof(IContentCmdletProvider))] instead. ;-)

Additionally, you can place multiple ProviderConstraint attribs on a cmdlet; in conjunction with this, there is a new protected property exposing an enum called "ConstraintPolicy" on PscxPathCommandBase (I'm probably going to change this to a virtual getter instead). This can be set to either EnforceOne or EnforceAll which enforces at least one, or enforces all. The former is useful when you decide to support both the FileSystemProvider AND the Registry for example, and the latter is useful if you want to enforce multiple interfaces like IContentCmdletProvider and ISecurityDescriptorCmdletProvider without specifying a particular concrete implementation. This is very useful for generic commands like Set-Owner/Get-Owner for example which could work against the filesystem, registry or even our directoryservices provider (if we get security working on it). The is another method, OnProviderConstraintViolation(PscxPathInfo pscxPath, Type expectedType) that is called for every violation. You may override this and do what you wish; the stub writes an ErrorRecord containing a generic message explaining that the path provided is not suitable for this command.

Currently the automatic checks are only performed on LiteralPath and Path, but there is a protected method called IsConstraintViolated(PscxPathInfo) which can be called for custom parameters (like OutputPath etc) which will check against any stated constraints.

Also, don't forget to call base.BeginProcessing() or the constraint stuff won't work. I need to put an initialization check in there somewhere and throw if people forget to call the base method...

I'm working on a larger post detailing stuff better, but you prompted me into this mini summary. Again, this is just a start on this stuff, so suggestions of possible flaws/issues/bad smelss in this direction are always welcome, but may be subject to intense debating :D

- Oisin / x0n
Sep 20, 2007 at 9:24 PM
Very nice and convenient! I'm going to use it.
Regarding the PscxCmdlet.BeginProcessing check, I think there are going to be more places which will need it (e.g. the Context property, perhaps others)