In a continuation of what is, sadly, becoming a series on how the PowerShell Pipeline works … Karl Prosser brought to my attention that certain powershell commands which have an -InputObject parameter don’t actually work when you pass something into it … so I thought I should create a cmdlet to show you how to correctly handle the InputObject parameter with the ValueFromPipeline set so you can pass the input in either way.

To demonstrate the problem, try this:


$a = @("A","B","A","C")
$a | Select -First 3 -Unique
Select -First 3 -Unique -InputObject $a
 

This should expose two weirdnesses about how the Select-Object cmdlet works:

  1. The -First parameter affects the input before the -Unique parameter does.
  2. When you pass the input in via -InputObject, the whole array is treated as a single object, and the command basically doesn’t do anything.

The big problem with this behavior is that there’s essentially no hint that you’ve done something wrong — there’s actually no way to make Select-Object work properly except by passing the objects in via the pipeline. The bigger problem is that it would have been simple for the Microsoft team to catch this and alert you, but they didn’t — so you probably won’t even notice there’s a problem until you run it on a trivial data set like my example. The even bigger problem is that it doesn’t just affect Select-Object (try it with Where-Object, just for instance). (more…)

Microsoft has provided some very good documentation on how to package fonts with WPF applications, and I’ve been following it in several different ways in different apps I’ve written. Recently I provided a feature in Posh Console which allows you to load the startup banner from an external file: StartupBanner.xaml.

Loading the banner from an external XAML file means that users can configure their own startup banner and make it look however they like, but it broke our default banner. The startup banner we’ve been using has a logo and some text which are all defined in pure XAML and uses several fonts which we had embedded in a FontLibrary.dll resource assembly. It worked great as long as the XAML was defined in the application, but as soon as we removed it to an external file and loaded it in using the XamlReader.Load method, the fonts all went to the fallback default fonts instead of our embedded ones.

Normally this might not be a big deal, but since our logo is based on the “Q” in a Quake-like font … it looks really lame without fonts. :D Apparently, when you load external XAML, it can’t use the Font Resource Library resources. At this point, I can’t seem to find anything to indicate why this is the case, but I suspect it has to do with the fact that the external, loaded XAML only has partial trust, and since the font is in an external assembly instead of embedded in the partial trust content, it can’t get to it. However, it might be simpler than that: it might just be that the base URI for the externally loaded XAML is an actual file location rather than one of the pack://,,,application/ type URIs, so the slightly odd font path doesn’t resolve.

In any case, I found a way around it, which is of course, why I’m writing all of this down. :) (more…)

So, I’ve been working on PoshConsole for awhile now, and with the help of some of the guys in #PowerShell@irc.freenode.net have been playing with trying to find ways to enhance output, like using ANSI escape sequences, and even creating an Out-WPF cmdlet which can output objects as databound WPF controls which look really good.

We have been trying to find a way to incorporate the colored and even bold/italic formatting in a way that would be compatible with the existing format-* cmdlets, and we’ve even looked at replacing out-default with a cmdlet that would be compatible with the default PowerShell host. But today I finally locked in on the import of this post on the PowerShell blog. It’s just not possible.

The format cmdlets (Format-List, Format-Custom, Format-Table, Format-Wide) output data in the form of undocumented .Net objects which are “subject to change without notice,” and are therefore basically useless. Of course, that means that if you want to replace Out-Default you have to not only replace the output, but you have to replace the formatting cmdlets, and of course the Update-FormatData cmdlet too — in fact, you have to either parse the largely undocumented format data files, or create some replacement for them to allow users to specify formatting for types you haven’t thought of…

All of this amounts to what many of you probably already knew: it’s a lot of work to create a complete PowerShell host, but it’s at least as much work to create a replacement PowerShell formatter.

So, I’ve been practically invisible for a few weeks here, and liable to be invisible for at least one more week … this is my vacation time, so it’s hard to motivate myself to blog about anything. However, I have been spending some time working on a side project: a PowerShell Host.

Now, there are a few other hosts out there, but with PowerShell Analyzer seemingly swallowing up PowerShell IDE and going the fifty dollar route … as an open sourcer and contributor to the PowerShell Community Extensions it seemed to me that this couldn’t be that hard, so I started looking for an open source implementation of PSHostRawUserInterface and couldn’t find one. I mean, there are a couple of implementations out there, but essentially they are the PowerShell Remoting interface (which actually runs inside PowerShell.exe, and thus doesn’t seem to implement anything itself) and a half-implemented console block from a Japanese file manager called kuon

So, being myself, I stepped in an implemented it in the weirdest way I could think of: on top of a WPF RichTextBox. Yep, that’s right. I’ve made myself a ConsoleTextBox which subclasses the RichTextBox and handles keyboard input etc to behave … roughly … the way a Console should.

It’s far from finished, but it is working, so this is by way of announcing the first public alpha release of PoshConsole! The vast majority of PowerShell scripts will run without a hitch — the only time you’ll have problems is with secure string input (eg: passwords), with direct raw buffer interaction, and with running “legacy” console applications — it does not yet redirect standard input/output/error.

One small tip: if you have the PowerShell Community Extensions installed, you’ll want to remove the alias they set up to pipe help through “less” ... because less is a legacy console app — you won’t get any help at all.

Technorati Tags: , , ,

So, a buddy was showing off the “say” command in the Mac OS X terminal the other day (my 3 year old daughter was vastly entertained) and I wondered what it would take to do the same thing in Windows PowerShell … it turns out the answer is, not much. :) You just type this into the console:


$Voice = new-object -com SAPI.SpVoice
$Voice.Speak( "Hello World!", 1 )

 

The cool thing about this is that it’s async, unlike the Mac “say” command, so you can go on typing the next command while it’s speaking. On top of that, you can have it read a text file by just changing that 1 to a 5:


$Voice = new-object -com SAPI.SpVoice
$Voice.Speak( "C:\Text\HolyGrail.txt", 5 )

 

Now, being who I am, and what I am, I wasn’t content with that, so I wrote myself up a script, Out-Speech, that will speak whatever it’s given (an array of objects as an argument, or the pipeline objects … ) and exposes most of the options of the underlying Speech API.

(more…)

I’ve been crazy busy the last few weeks, but I’ve been really rather distracted from my main project and it’s past time I got back to it. To really feel like I’ve moved on, I need to write a bunch of articles here and publish a couple of cool apps and some source code so that I can feel like I’ve reached a release point. What I’ve been playing with in all this coding is the new technology that’s been coming out of Microsoft in the last couple months: PowerShell, .NET 3 and WPF, and Windows Vista so you may or may not actually be able to use these apps …

The Vista Thumbnailer is a really slick little app that shows off some of what Vista can do … and some of what WPF can do. I’ll write more about it in the morning, because there’s some interesting things I learned in the coding of it, but in the meantime, you can download Vista Thumbnailer (7-Zip file with a config file). The only thing you really need to know is that there’s a hotkey: Win+X which will bring Thumbnailer back to the foreground even if it’s minimized in the tray. I’ll make the hotkey configurable in version 2, but for now you’re stuck with Win+X. The rest you can figure out from the screenshots (0 1 2) and by reading the tooltips on the buttons.

Play around. Let me know what you think.

(Oh, source code is here with your usual choice of BSD/Ms-PL/GPL)

[New] Edit: Continuing

So … I’ve had a lot of questions about this app during it’s development (from a few friends in our IRC channel) so it’s clear that I should try to at least give the highlights of how it works.

Thumbnails

By now you’ve probably seen more than your fill of screenshots of Windows Vista’s semi-transparent windows, and maybe you’ve had a chance to try Vista and seen these live-updating thumbnails on the Alt+Tab window, the Flip3D Win+Tab task switcher, and even the task-bar’s mouse-over (or Win+T) popups. All of this is possible because of the way Windows does desktop compositing using a new Desktop Window Manager. This DWM is actually a process which runs all the time when you have the “Aero” interface turned on, but it’s also an API exposed through dwmapi.dll … and one of the deepest fundamental changes to the way Windows work in Vista. Let me quote from “one of the developers” blogs:

... The way an application gets pixels on the screen has fundamentally changed. [In the past] applications were asked by Windows to paint their visible region, and they would paint directly to the buffer that was to be displayed by the video card. With Windows Vista, applications are asked by Windows to paint their entire surface to an offscreen surface (alternatively known as a bitmap, buffer, or texture), and it’s up to the DWM to take all of these offscreen surfaces, and “compose” them together to the onscreen buffer.

Because the windows are rendered “offscreen” and without regard to what part of the window might actually be visible … the visual representation can be reused in many places very cheaply — that is, since the visual representation is just a cached picture, there’s very little CPU cost involved in repainting it in many places … and the caching and repainting are easily handled by the DWM. Now, the DWM also does lots of other cool things, like using DirectX and hardware accelleration to do all this extra rendering of these cached surfaces, but despite appearances, this isn’t really an article about the DWM — we’re here to talk about JUST the thumbnails. Greg Schechter again:

Thumbnails in the DWM are not static snapshots of a window. They’re dynamic, constant connections between a thumbnail source window, and a place on a target window that that source window will get a “thumbnail rendering”.

Basically, the APIs in the Desktop Window Manager allow you to ask for a certain portion of one Window’s screen to be painted over (at some specified level of opacity) with all or part of the contents of another Window’s screen. In every sense, the thumbnail is just as live and up-to-date as the actual window (since it is, in fact, being painted by the same process).

So anyway, what I did is I took a “Thumbnail” class from Douglas Stockwell and enhanced it a bit … it’s still not quite perfect, but it’s trivially easy to use now: just pass it a Window handle and it hooks itself up and renders within it’s available bounds — mostly.

Glass Effect

The Vista Thumbnailer app also showcases a couple of other slick API features. First, I added a couple of simple wrappers to DwmExtendFrameIntoClientArea and DwmIsCompositionEnabled so that you can easily get the translucent “glass” effect on your whole window, or write, for instance: if( !NativeMethods.IsCompositionEnabled ) { MessageBox.Show( "Sorry you can't use this feature!" ); }

Hotkeys

I also wrote a global hotkey manager class which can be easily added to WPF applications that want to register global hotkeys. VistaThumbnailer only has one, to focus it (you can change it by editing the .config file).

These are global hotkeys, not like the “Ctrl+O” for opening a file, but like the Win+R to bring up a run dialog. They’re registered through Window’s RegisterHotkey and UnregisterHotkey APIs, and you get notified of them via window messages (but my HotkeyManager class will handle the WM_HOTKEY message for you). Here’s the short-form for how to use them (you can grab the source if you’d like to borrow the class, but I’ll be re-releasing this in a few days with some enhancements I’ll detail below).

using GeoCore.Win32;

public class Window1 : System.Windows.Window {
   private WPFHotkeyManager hkManager;
   // You need to keep a reference to the hotkey around
   // Otherwise you won't know *which* hotkey was pressed!
   private Hotkey focusHotkey; 

   public Window1() {
      // ... somewhere ... hook SourceInitialized (you can do it in the XAML)
      SourceInitialized +=new EventHandler(Window1_SourceInitialized);
   }
   
   void Window_SourceInitialized(object sender, EventArgs e)
   {
      // make the whole window glassy, preserving the border
      NativeMethods.TryExtendFrameIntoClientArea(this, BorderThickness);

      // create the hotkey manager in "SourceInitialized" because
      // it doesn't accept hotkeys anyway until the window is Initialized
      // -- this is because it needs a window handle.
      hkManager = new WPFHotkeyManager(this);
      // register for the hotkey event, otherwise ... nothing happens.
      hkManager.HotkeyPressed += new WPFHotkeyManager.HotkeyPressedEvent(Hotkey_Pressed);
      // create a hotkey -- remember, this is global (and be careful of the types here)
      focusKey = new Hotkey(ModifierKeys.Win, Keys.X);
      // register the hotkey
      hkManager.Register(FocusKey);
   }


   void Hotkey_Pressed(System.Windows.Window window, Hotkey hotkey)
   {
      // an action for each hotkey ....
      if (hotkey.Equals(FocusKey))
      {
         Show(); Activate();
      }
   }
}
 

I want you to notice that I had to create my own Keys enumeration in this, because the WPF developers unbelievably chose to use an ordering for their Key enumeration which is inconsistent with the Windows API ordering. You could use the System.Windows.Forms enumeration, but that would require adding a reference to the Forms assembly in your WPF application just to get a silly enum! I have to say that this seems to be absolutely the WORST design decision I’ve seen in the .NET Framework — not only are they duplicating enumerations which exist elsewhere, but they couldn’t even copy-and-paste it in order?

Chrome Free Windows!

I thought I’d mention this, just in case you haven’t seen it before. Irregular shaped windows are trivially easy to do in WPF. All you have to do is add the following attributes to your Window tag: WindowStyle=“None” AllowsTransparency=“True” Background=“Transparent”

Further Development

DWM API Thumbnails

There are still a few tweaks that need to be made to the Thumbnail Image control. It doesn’t adjust when the source window is changed until you resize the window (because it doesn’t check the size except when WPF asks it to) and I’m not sure if it’s possible apart from re-checking the source window shape on a timer. I’m a little afraid that I’m leaking the thumbnail window so I need to wrap them in a Safe Handle, and override OnUnloaded to clean up.

I’m also curious if there’s a way, in the DWM api, to get these thumbnails batched into a video or saved to an image handle so you can use them for screenshots … I’ll have to take some additional time to research that.

Hotkeys

There’s also some changes I want to make to the way my hotkeys class works. Right now you have to hang on to your Hotkey objects in order to be able to process the hotkey events correctly (unless you only have a single Hotkey) ... and it’s not possible to use a switch statement on the event, so if you have a lot of hotkeys, it gets a bit ridiculous. I initially did this because I didn’t like trusting the user to come up with unique Hotkey Id’s, but now I’m thinking that it might be better if you could use just the Ids and create yourself an enumeration for them. I need to play with this, because one of my key use scenarios is having windowless plugins be able to register and process their own hotkeys — which makes enums not completely safe, because different pieces of code are dynamically creating hotkeys.

I also don’t like not being able to register the hotkeys during construction. My first attempt to fix that is a version of this HotkeyManager (which I’ll release shortly) that creates it’s own window — this means you don’t have to worry about calling it in SourceInitialized, but it’s a pretty expensive fix if you’ve already got a window. I’m going to try doing it another way — where hotkeys registered before the handle is initialized will be queued for registration later, and this should be a better solution in most cases. I do have a System.Windows.Forms version (which I will release with all the other versions) that doesn’t have this problem (because with Windows.Forms you get a window handle on construction), but again, I don’t like including that whole assembly for something fairly trivial.

Hopefully I’m going to get better at these writeups as time goes on, because I feel like this one is a bit rambling. Questions and comments are welcome!

I wrote ShotGlass, for various reasons
It does lots of things
It’s licensed for free...

And there’s a new version … make sure you have beta 2 of the .NET Framework Version 2.0 then, download ShotGlass build 1.1 and unzip it wherever you want it.

The changes from the last version are mostly minor, they relate to the way the form and the thumbnail window behave when you’re resizing them or moving them. The big news, however, is that I’ve included a new plugin for uploading images to Gallery2 using their HTTP POST API (the one that their Gallery Remote uses) . It won’t work with the old Gallery 1.x galleries, but it works a treat with RC2 for Gallery 2, which is what the GeoShell site uses for our screenshots gallery … which was half the reason I wrote this whole application anyway. I also added a JPEG output plugin, so you don’t have to upload those huge uncompressed PNG’s to your webserver’s gallery…

I’ll publish the simple API tommorrow, but for now, the source is here under the MIT License... if you make improvements, please be kind enough to send them back to me :D

I wrote my own screenshot app called ShotGlass, which does all sorts of things and is released for free under the MIT License, which basically means that ShotGlass is free for you to do pretty much whatever you like, as long as you don’t expect me to guarantee it or provide service, or in any way be responsible for what might go wrong.

The official license is as follows:

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Here’s the download

I wrote about why I wrote my own screenshot app called ShotGlass, here’s what it does:

ShotGlass takes screenshots!

  • Crops screenshots!
    • Optionally, it crops the screenshot to the ShotGlass Window.
    • Optionally creates thumbnails
      • When taking a “cropped” shot of just the area covered by the ShotGlass window, the thumnail is created from a positionable sub-window.
      • When taking an uncropped screenshot of the full screen, uses the main window as the thumbnail cropper.
  • Can automatically resize the screenshot crop area to match the size and shape of the window you want to take a screenshot of. Just put the top left corner of the ShotGlass window over the window’s title bar.

It also uses plugins to enhance functionality:

  1. Image processing “Mixer” plugins. I’ve provided a watermark plugin which does images and text, and a highlight plugin which uses the thumbnail area to highlight a portion of the screen in the shot. But anything you can imagine in image processing can be done with an extremely simple interface.
  2. Image output “Glass” plugins which control the file output. The default one is to output to the clipboard, but I’ve already included ones for Png and Bmp output, and I’ll put one in later for Jpg with compression.
  3. File handling “Drinker” plugins which can upload the file, or basically do whatever you want to do with the screenshot files once they’re saved. I’ve already included one for FTP uploading, and I’m working on Gallery uploads for my original geoShell purposes.

And finally, it has command-line features:

  • Named configs, so you can specify a config (which is saved on-exit) using /config:configname This allows you to set up different types of shots which you can take later, because …
  • Take a cropped screenshot “instantly” (without ever showing the UI) if you pass the parameter: /instant
  • Take a full screen shot instantly using: /fullscreen

I’ll put up more information here later, including screenshots of the very nice configuration panel and the right-click menu (which includes documentation of the hotkeys), but for now I want to get on with getting this beta release out so I can get some feedback.

Here’s it’s release license...
Here’s the download

I’ve been using Cropper for a while to take simple cropped screenshots, but when I want to take a screenshot of my whole screen, I keep having to go back to my old screenshot script which uses ImageMagick and commandline ftp, because I need to upload the screenshot. Recently I realized I want to upload the images to Menalto gallery on the geoShell site and I wanted to share that ability with other people, but my script requires ImageMagick and Perl to be installed and properly configured, which seems a bit to ask of your average Windows user ;)

I started out to write a plugin for Cropper but ended up deciding there were just too many things I didn’t like:

  • The plugins are rather more complicated to write than they need to be, partly because they have to handle ALL the output…
  • The thumbnail window is locked at the center of the screenshot window
  • There’s not really any way to take a shot of the full screen
  • There’s no command-line ability (you have to bring up the cropper window to take a screenshot)

The end result is that I’ve written myself a screenshot application. Now, I wrote it mostly for myself, at first, so I wrote it in C#, using Beta 2 of Visual Studio. Eventually I decided to “fix” the shortcomings I saw in other implemenations, but I don’t really want to back-port it to .NET 1.1, so in order to use it, you need to have beta 2 of the .NET Framework Version 2.0 installed.

Here’s it’s release license...
Here’s what it does
Here’s the download