BgShell – Background Shell



[Download: BgShell.zip]


BgShell is a proof of concept PowerShell host that explores the idea of “PowerShell Everywhere.”


What if PowerShell was always at your fingertips – making quick calculations easier than launching Windows Calculator? Or, making a “quick ipconfig” with PowerShell just a keystroke away? BgShell offers PowerShell Everywhere, and instant gratification. Simply press Control-Alt-B, and the BgShell interface appears immediately. Press Control-Alt-B again to hide the shell. Closing the window only hides the shell, keeping it instantly available for your next command.


The concept of “PowerShell Everywhere” goes further than that, though. What if you could bind PowerShell script blocks to arbitrary keystrokes? BgShell supports that, too. If you use any keyboard Macro programs, BgShell can likely replace them — and with a more powerful engine and scripting language, at that.


BgShell lets you define these in a host-specific profile. If you tend to write the same thing over and over, just define a hotkey for it:



## Boy, I type this a lot.
$keyMapping[‘Control,Alt,Q’] = @{ 
    Action = { SendString ‘PowerShell Rocks!’
}


 


Or, rather than batting the mouse cursor out of the way when it obscures your typing, just press a hotkey:



## Move the annoying mouse pointer out of your way
$keyMapping[‘Control,Alt,Z’] = @{ 
    Action = {
        [Windows.Forms.Cursor]::Position = (New-Object System.Drawing.Point 0,0
    }
}


 


Or even bring some of your old Unix habits to the Win32 console:



$keyMapping[‘Control,L’] = @{
    KeypressHandled = { IsClassActive ‘ConsoleWindowClass’ };

    ## Console clear
    Action =  { SendKeys ‘{ESC}cls{ENTER}’ }
}



 


At the same time, you’ve been building new habits in PowerShell. Why not cater to them?



$keyMapping[‘Control,F’] = @{
    KeypressHandled = { IsClassActive ‘ConsoleWindowClass’ };

    ## Console foreach-object
    Action =  { SendString ‘| foreach { $_. }’; SendKeys ‘{LEFT}{LEFT}’ }
}


 


Keystroke automation of other programs opens up entire new realms of interactive management potential:



## Control,Alt,C — Convert selected text in an Outlook Message
## into a code sample
$keyMapping[‘Control,Alt,C’] = @{
    KeypressHandled = { IsClassActive ‘_WwG’ };
    Action =  { 
        Start-Sleep -m 100
        SendKeys “%o”
        Start-Sleep -m 500
        SendString “ff”
        Start-Sleep -m 500
        SendString “Courier New”
        SendKeys “{ENTER}”
        Start-Sleep -m 500
        SendKeys “%o”
        Start-Sleep -m 500
        SendString “fs”
        Start-Sleep -m 500
        SendString “9”
        SendKeys “{ENTER}”
        Start-Sleep -m 500
    }
}


 


Of course, your brain starts to hurt with so many hotkeys. In that case, maybe a memorable phrase is better?



## Get the current date


$stringMapping[ “**date” ] = { SendString (Get-Date) }


 


How about saving yourself from the tedium of template code?


## Get some input from the user
function Get-Input
{
param ($message = “Input : “,
$title = “Inputbox”)

$vbs = New-Object -com MSScriptControl.ScriptControl
$vbs.language = ‘vbscript’
$vbs.addcode(“function getInput() getInput = inputbox(`”$message`”,`”$title`”) end function”)
$result = $vbs.Eval(‘getInput’)
$result
}

## Generate a C# property
$stringMapping[ “**prop “ ] =
{
$template = @”
/// <summary>
/// Summary of what this property does
/// </summary>
public __TYPE__ __NAME__
{
get
{
return __NAMELOWER__;
}
set
{
__NAMELOWER__ = value;
}
}
private __TYPE__ __NAMELOWER__;
“@

$type,$name = (Get-Input -Message “Property type and name, such as ‘String Foo': “) -split ” “

$template = $template.Replace(“__TYPE__”, $type)
$template = $template.Replace(“__NAME__”, $name)
$template = $template.Replace(“__NAMELOWER__”, ($name.Substring(0,1).ToLower() + $name.Substring(1)))

$autoIt.ClipPut($template)
}


 


The sky really is the limit.


For more examples, see the example profile. Place it in the same directory as your regular PowerShell profile. BgShell surfaces this profile location through the standard $profile variable.


 


Note


·         Vista introduces security enhancements that prevent low-privilege applications from being notified of keystrokes in (or sending keystrokes to) high-privilege applications. BgShell is marked to run as administrator so that it can respond in elevated windows.

7 Responses to “BgShell – Background Shell”

  1. Steven Murawski writes:

    Thanks Lee!

    I had one problem getting it to run on V1.0. I had to change the -split operator on line 368 of the sample profile to

    $type,$name = (Get-Input -Message "Property type and name: ").split(" ")

    from

    $type,$name = (Get-Input -Message "Property type and name: ") -split " "

    because -split is only available in the CTP.

  2. Steven Murawski writes:

    One more thing, the History Search uses a script from your book, which people might not have – Select-FilteredObject.

  3. Chris Harris writes:

    Hi Lee,
    I love the idea, but bgShell isn’t working for me. I’m running Vista 64-bit with SP1 and it’s a very new/clean machine that I just built last week.

    When I start bgShell it looks like it’s going to work, but as soon as I do something (i.e. type and hit enter) it crashes with the following error:

    Problem signature:
    Problem Event Name: APPCRASH
    Application Name: BgShell.exe
    Application Version: 1.0.0.0
    Application Timestamp: 47f02fd6
    Fault Module Name: ntdll.dll
    Fault Module Version: 6.0.6001.18000
    Fault Module Timestamp: 4791adec
    Exception Code: c0000005
    Exception Offset: 0000000000047960
    OS Version: 6.0.6001.2.1.0.256.6
    Locale ID: 1033
    Additional Information 1: d169
    Additional Information 2: 274489c7e8c7856a0e4ae0b817e3eb56
    Additional Information 3: 7f6a
    Additional Information 4: b758d997a347ee4da2d613b4934d7e80

    Read our privacy statement:
    http://go.microsoft.com/fwlink/?linkid=50163&clcid=0x0409

    Any ideas?

    Thanks,
    Chris

  4. moff writes:

    sorry to be stupid, but how do I get going with this?
    I’ve copied the autoit dll to my windows dir and it’s registered. I’ve put the Microsoft.BgShell_profile.ps1 in my powershell profile dir. If I execute it from a PS session I don’t get an error.
    Now what?
    If I run BgShell.exe from PS or double-click in Explorer, I just get "BgShell has encountered a problm and need to close"
    am I missing something obvious?
    OS in Windows Server 2003, running as a local admin.

  5. Lee Holmes writes:

    Hmm, there seems to be an issue on some systems. I haven’t had any luck tracking it down yet, though. I’ll keep on looking.

  6. Brian Adams writes:

    Just found bgshell. Nice. Anyway to register CapsLock as the hotkey? I’ve tried but no dice…

  7. Jay Bazuzi writes:

    Consider sharing the source, perhaps on CodePlex. It would be good for us to have another example of creating a custom host & other things we could learn about. It also would give us the chance to offer improvements.

Leave a Reply