Command Prompt and PowerShell Here with Console.exe

command-hereIn antediluvian turn of the century days, there was an Open Command Window Here PowerToy. When Vista was released, this functionality was baked in to the default Explorer shell. Hold {SHIFT} and right-click on a drive, directory or the background of a directory and you will have an “Open command window here” option in the resulting context menu. Although PowerShell is installed by default on Windows 7, there is no parallel “Open PowerShell window here” option, but it can be easily added.

“Open PowerShell window here”

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Directory\shell\powershell]
@="Open PowerShell window here"
"Extended"=""
[HKEY_CLASSES_ROOT\Directory\shell\powershell\command]
@="C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe -NoExit -Command Set-Location -LiteralPath '%V'"

[HKEY_CLASSES_ROOT\Directory\Background\shell\powershell]
@="Open PowerShell window here"
"Extended"=""
[HKEY_CLASSES_ROOT\Directory\Background\shell\powershell\command]
@="C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe -NoExit -Command Set-Location -LiteralPath '%V'"

[HKEY_CLASSES_ROOT\Drive\shell\powershell]
@="Open PowerShell window here"
"Extended"=""
[HKEY_CLASSES_ROOT\Drive\shell\powershell\command]
@="C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe -NoExit -Command Set-Location -LiteralPath '%V'"

Use Console.exe Windows

If you use command-line a lot in Windows, you will appreciate the advantages of using console.sf.net as the terminal window. The “Open … window here” context menus can be tweaked to open the new command prompts in Console rather than vanilla Windows CSRSS console windows.

"Open command window here” with Console

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Directory\shell\cmd]
@="@shell32.dll,-8506"
"Extended"=""
"NoWorkingDirectory"=""
[HKEY_CLASSES_ROOT\Directory\shell\cmd\command]
@="\"C:\\Program Files\\Console2\\Console.exe\" -r cmd.exe -d \"%V\" -w \"Command Prompt\""

[HKEY_CLASSES_ROOT\Directory\Background\shell\cmd]
@="@shell32.dll,-8506"
"Extended"=""
"NoWorkingDirectory"=""
[HKEY_CLASSES_ROOT\Directory\Background\shell\cmd\command]
@="\"C:\\Program Files\\Console2\\Console.exe\" -r cmd.exe -d \"%V\" -w \"Command Prompt\""

[HKEY_CLASSES_ROOT\Drive\shell\cmd]
@="@shell32.dll,-8506"
"Extended"=""
"NoWorkingDirectory"=""
[HKEY_CLASSES_ROOT\Drive\shell\cmd\command]
@="\"C:\\Program Files\\Console2\\Console.exe\" -r cmd.exe -d \"%V\" -w \"Command Prompt\""

“Open PowerShell window here” with Console

 

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Directory\shell\powershell]
@="Open PowerShell window here"
"Extended"=""
[HKEY_CLASSES_ROOT\Directory\shell\powershell\command]
@="\"C:\\Program Files\\Console2\\Console.exe\" -r C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe -d \"%V\""

[HKEY_CLASSES_ROOT\Directory\Background\shell\powershell]
@="Open PowerShell window here"
"Extended"=""
[HKEY_CLASSES_ROOT\Directory\Background\shell\powershell\command]
@="\"C:\\Program Files\\Console2\\Console.exe\" -r C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe -d \"%V\""

[HKEY_CLASSES_ROOT\Drive\shell\powershell]
@="Open PowerShell window here"
"Extended"=""
[HKEY_CLASSES_ROOT\Drive\shell\powershell\command]
@="\"C:\\Program Files\\Console2\\Console.exe\" -r C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe -d \"%V\""

 

 

Restore Defaults

For PowerShell, remove the powershell keys from beneath HKCR\Directory\shell, HKCR\Directory\Background\shell and HKCR\Drive\shell.

“Open command window here” restore default

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Directory\shell\cmd]
@="@shell32.dll,-8506"
"Extended"=""
"NoWorkingDirectory"=""
[HKEY_CLASSES_ROOT\Directory\shell\cmd\command]
@="cmd.exe /s /k pushd \"%V\""

[HKEY_CLASSES_ROOT\Directory\Background\shell\cmd]
@="@shell32.dll,-8506"
"Extended"=""
"NoWorkingDirectory"=""
[HKEY_CLASSES_ROOT\Directory\Background\shell\cmd\command]
@="cmd.exe /s /k pushd \"%V\""

[HKEY_CLASSES_ROOT\Drive\shell\cmd]
@="@shell32.dll,-8506"
"Extended"=""
"NoWorkingDirectory"=""
[HKEY_CLASSES_ROOT\Drive\shell\cmd\command]
@="cmd.exe /s /k pushd \"%V\""

The Stack is an Implementation Detail

c-sharpI have a confession. When .NET and C# beta came out in 1999, I was confused by the definition of struct as a “value type” allocated on the stack and class as a “reference type” allocated on the heap. We were told structs are lean and fast while classes are heavy and slow. I distinctly recall searching for every imaginable opportunity to use the struct keyword. I further recall being confused by the statement that everything in C# is passed by value and by the ref and out keywords. I used ref whenever I wanted to modify values in a formal parameter regardless of whether they were structs or classes. What I didn’t realize at the time was that ref and out are really just an explicit use of a pointer. Ref and provide a mechanism to manipulate a value type by pointer instead of manipulating a local copy. For reference types, though, using ref and out is the moral equivalent of using a pointer-to-pointer in C and it is rarely necessary or correct.

Eric Lippert has a could of blog posts about how the stack is an implementation detail and not really the point of value types at all. He flat-out stays that the guidance about stacks and heaps is useless and confusing. The point of value types is that they are always copied by value rather than just having another variable point (refer) to the same memory as with a reference type. They just happen to be placed on the stack because they can.

Along the way he explains why you can’t capture a ref value type in a closure.

Something like su(1) for PowerShell and Console

If you have your day-to-day account configured as a limited user and not a member of the Administrators group, you have to elevate to switch users or use the runas service to do some system configuration tasks. If you already have a shell open anyway, the runas comand-line is probably what you want, but the syntax of the command is a little verbose. I have a basic su-like su for PowerShell that opens a new PowerShell session in a new Console window running with the credentials you gave to su. By default it tries to log you in as the built-in administrator account (which is disabled by default on Windows Vista/7).

su.ps1

#emulate UNIX su behavior
#start a new powershell instance with a different user account context

param( [string] $username )

function Substitute-User( [String] $username )
{
	if( !$username )
	{
		#look up the built-in Administrator account using WMI. 
		#the built-in administrator has a SID that starts with S-1-5 and ends with -500.
		$accts = get-wmiobject win32_useraccount
		foreach( $acct in $accts )
		{	
			if( $acct.SID -match '^S-1-5-.+-500$' )
			{ 
				$username = $acct.Caption
				if( $username -match "[^\\]+$" )
				{	
					$username = $matches[0] 
				}
				break
			} 
		}
	}
	$credential = Get-ConsoleCredential( $username )
	$startinfo = new-object Diagnostics.ProcessStartInfo
	$startinfo.UseShellExecute = $false
	$startinfo.FileName = "$env:programfiles\Console2\Console.exe"
	$startinfo.UserName = $credential.UserName
	$startinfo.Password = $credential.Password
	$startinfo.Arguments = "-r $pshome\powershell.exe -d `"$pwd`""
	$startinfo.WorkingDirectory = $pwd

	trap [ComponentModel.Win32Exception]
	{
		if( $_.Exception.NativeErrorCode -eq 267 )
		{
			write-host "$pwd is an invalid directory for $username."
			write-host "Starting PowerShell in ${env:SystemRoot}\system32."
			$startinfo.Arguments = "-r $pshome\powershell.exe -d ${env:SystemRoot}\system32"
			$startinfo.WorkingDirectory = "${env:SystemRoot}\system32"
			$null = [Diagnostics.Process]::Start( $startinfo )
		}
		else 
		{	
			$_.Exception.Message
		}
		continue
	}
	$null = [Diagnostics.Process]::Start( $startinfo )
}

#Generate a PSCredential object without creating a pop-up security dialog like 
#the built-in get-credential cmdlet.
function Get-ConsoleCredential( [String] $username=$( read-host 'Username' ) )
{
	while( !($username) )	
	{
		$username = read-host 'Username'
	}
	$passwd = read-host -asSecureString 'Password'
	new-object Management.Automation.PSCredential $username, $passwd
}

Substitute-User $username

Boot Camp: Dated Broadcom Driver Causes Audio Pops and Crackles

broadcom-disable-802-11aI have had a problem with my MacBook Pro having intermittent crackles and pops in the audio in my late 2009 Macbook Pro Unibody. I previously suspected the Cirrus Audio driver.  Restarting “Windows Audio” (aka audiosrv) fixes the problem. The pattern is that everything is fine on boot. The crackles and pops start after resuming from sleep.

I just came across this post which indicates the problem is actually caused somehow by the the 802.11a feature of the Broadcom wireless network adapter. Somewhat incredulously, I gave this a try and it works so far.

It also seems that although, Apple has not seen fit to send out an update, Broadcom has published several newer versions of their 943XX driver. These are available from other OEMs using Broadcom chips (Acer, Dell and HP) that actually provide updates for Windows drivers on a regular basis. HP helpfully offers a version of the Broadcom Wireless driver that is almost a year newer than the one in Boot Camp 3.1. The revision history of here shows notes a series of performance enhancements over the Apple-distributed version 5.60.18.8.

Update

Some good folks have taken it upon themselves to scrape together Broadcom wireless driver downloads posted by various OEMs. Note that sometimes the stuff in the forums is newer than what is listed in the pinned initial post. At the time of this writing, the latest available is 5.100.249.2 from Acer.

Update 2

I’m still getting the intermittent pops and crackles. Perhaps I have unfairly maligned the Broadcom driver based on random info from the interwebs. I just realized that the speakers on my Cinematic Display are running at the same time as my nice speakers on the mini-jack. Maybe that has something to do with it. Still futzing.

Upgrade and Zenburn the Console Window

Background

In Windows, console windows (aka command line or “DOS” windows) are special. In a UNIX-like environment a terminal emulator talks to a local virtual teletype and connects to three text streams: standard in, standard out and standard error. From the first version of Windows NT to now, the client-server runtime subsystem automatically creates a special window environment for any command-line program or shell. In fact, up until Windows 7, the window was actually owned by csrss.exe which runs with system privileges. These windows mostly look like the rest of Windows but they are different in deep ways. Even if you remove the entire graphics and windowing infrastructure from Windows as in Windows Server Core, you are left with the GINA logon screen and a console window which looks exactly the same because the code to draw them is in csrss.exe rather than the normal window manager. That’s also the reason why they aren’t themed in Windows XP. Console Windows also can’t be resized in the usual way. On the other hand, Console windows offer a richer programming environment than sdtin,stdout and sderror because they always have a title bar and exist within a window station which means that services like the clipboard can be assumed. The gist is that for reasons of backwards compatibility and security, it is difficult for Microsoft to change very much about how console windows work. And besides, it’s a nerd feature that normal people never use.

powershell-standard-console-scrollbars

For me, there are some minor annoyances with console windows that I mostly try to ignore:

  1. Console Windows aren’t easily resizable. You have to change the definition of the rows and columns. Dragging the window borders either creates scrollbars or does nothing.
  2. Copy operates in a block mode rather than a line mode. That means if you copy text, you end up having to fix it where line breaks were added or you can accidentally leave out columns and end up with garbage.
  3. Marking for copy blocks the execution of anything trying to write to the window. This makes “Quick Edit” mode dangerous because clicking on the window tends to freeze it. Because of item 1 and 3, I end up creating giant console windows and leaving them that way. The shortcuts that PowerShell creates for itself do this by default.

Enter Console.exe

Its not easy to replace console windows with something else. If you use a terminal emulator with VTYs in the POSIX subsystem (like xterm in the POSIX/SUA subsystem) some console applications that expect to interact with the console window or the window station service won’t run at all or only work in a special mode, like PowerShell. Also, the VTYs exist in the POSIX subsystem and don’t have access to your current window station, so you can’t start windowing applications from a terminal on a VTY (like “explorer .” to open Explorer in the current command shell directory).

Console (aka Console2) is a modern terminal environment like a Gnome Terminal or Konsole  for Windows that is 100% compatible with applications that expect a console window running in a window station. That’s because it works by hooking and hiding the console window created by CSRSS while providing a richer user environment. I gave up on this thing when I started using Vista x64 because it was broken. It has matured a lot since then and the latest beta works great with Windows 7 x64.

  • Arbitrary window resizing by dragging the borders!
  • Copy selects lines and keeps line breaks intact like xterm et al. (Hint: the default is SHIFT+{mouse-select} to select, {mouse-click} to copy and {mouse-middle-click} to paste.)
  • Available tabbed environment.
  • Easily configure fonts without editing the registry.
  • Save multiple shell environments (like visual studio command prompt, cygwin, powershell, etc.)
  • Also, there are toys like transparency and background images.
  • All the key bindings and window layout stuff is configurable.
  • The windows console function key bindings (like F7 for history) still work.
    Unfortunately, selecting text still blocks the underlying windows console and therefore the execution of any script or application that might be generating text, but we get a configurable quick edit behavior where the defaults won’t have you accidentally selecting and blocking a window.

It Just Needs Zenburn

Zenburn is a low contrast color scheme originally developed for Vim and subsequently ported to almost everything. It’s a dark, low eye strain theme that is very addictive.

Here are Zenburn colors for console.xml:

 

<colors>
        <color id="0" r="62" g="62" b="62"/>
        <color id="1" r="100" g="100" b="175"/>
        <color id="2" r="0" g="128" b="0"/>
        <color id="3" r="0" g="128" b="128"/>
        <color id="4" r="51" g="35" b="35"/>
        <color id="5" r="170" g="80" b="170"/>
        <color id="6" r="220" g="220" b="0"/>
        <color id="7" r="220" g="220" b="204"/>
        <color id="8" r="192" g="128" b="128"/>
        <color id="9" r="175" g="175" b="255"/>
        <color id="10" r="127" g="159" b="127"/>
        <color id="11" r="140" g="208" b="211"/>
        <color id="12" r="227" g="113" b="113"/>
        <color id="13" r="200" g="128" b="200"/>
        <color id="14" r="240" g="223" b="175"/>
        <color id="15" r="255" g="255" b="255"/>
</colors>

Console.sf.net with Zenburn colors showing muted red error.zenburn-console

Console.sf.net with muted colors showing F7 history popup.zenburn-console-popup

Console.sf.net with Zenburn colors, multiple tabs and transparency. (The elephant is my desktop wallpaper.)

console-tabs-transparency

Use Image Hijacking to Globally Replace Notepad.exe

I like to use a progammer’s text editor called EmEditor. Some people like Notepad++, vim, etc. You can change file associations but some things are just hard-coded to call notepad.exe. Notepad.exe is a protected system file which makes it hard/unsafe to replace.

Instead of replacing it, you can hijack calls for notepad.exe and redirect them to another text editor by registering a fake debugger.

You just need a tiny script to capture the arguments being sent to notepad and send them to your text editor of choice, instead. Replace the paths in the example with the paths and text editor for your system.

Script

 var shell, args="",
    editor = "C:\\Program Files\\EmEditor\\EmEditor.exe";
if( WScript.Arguments.length > 0 ){
	for( i=1; i<WScript.Arguments.Length; i++ ){
		args += WScript.Arguments(i) + " ";
	}
	shell = new ActiveXObject("WScript.Shell");
	shell.Exec("\"" + editor + "\" " + args);
}

Registry

new-item 'HKLM:\software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe'
Set-ItemProperty 'HKLM:\software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe' -name  Debugger -value 'wscript "C:\Program Files (x86)\Utilities\replace-notepad.js"'

Update

It’s been pointed out by commenter “MM” that files with multiple spaces together in the name break the WScript hijack. In this scenario, the Dubugger redirect splits the file name on whitespace and discards the extra whitespace. I put together a little hijack in C# that fixes this problem as long as there aren’t two or more files with names that differ only by the amount of whitespace between words in the file name. If that’s the case, you’re out of luck and should probably think about why you are naming files this way. Otherwise, this slightly fancier hijack will handle files with multiple spaces separating words in the name.

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;

class Program
{
	public static void Main(string[] args)
	{
		string handler = args[0];
		
		if(args.Length == 3) Process.Start(handler, string.Format("\"{0}\"", args[2]));
		else if(args.Length > 3)
		{
			string dirplus = args[2];
			int index = dirplus.LastIndexOf("\\");
			var dir = new DirectoryInfo(dirplus.Substring(0,index));
			var filepart = dirplus.Substring(index + 1);
			var expression = filepart + "\\s+" + string.Join("\\s+", args.Skip(3));

			var names = dir.GetFiles(filepart + "*").Select(x => x.Name);
			var files = names.Where(x => Regex.IsMatch(x, expression));
			if(files.Count() > 1)
			{
				MessageBox.Show(
					string.Format("{0} possible matches found with file names that differ only by spaces between words.\r\nChoosing the first match.", files.Count()), 
					"Warning", 
					MessageBoxButtons.OK, 
					MessageBoxIcon.Warning);
			}	
				 
			Process.Start(handler, string.Format("\"{0}\"", files.First()));
		}
	}
}

> csc /target:winexe .\hijack.cs

In the regsitry, set the Debugger like this:

Set-ItemProperty 'HKLM:\software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe' -name  Debugger -value '"C:\Program Files (x86)\Utilities\hijack.exe" "C:\Program Files\EmEditor\EmEditor.exe"'

Replace Task Manager with Process Explorer x64

Process Explorer has a “Replace Task Manager” option. On x64 Windows, this doesn’t work right. Instead of replacing Task Manager, it ensures that Task Manager can never run.

This feature works through an image hijack. What is supposed to happen is Process Explorer is supposed to register itself as the debugger for Task Manager. It doesn’t act as a debugger, instead, it just launches itself.

Here is the garbage that gets written by default.

taskmgr-img-hijack-broken

The Debugger value should be the fully qualified path to where procexp.exe lives. Unfortunately, procexp wrote some garbage in there.

Set-ItemProperty 'HKLM:\software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\taskmgr.exe' -name Debugger -value "C:\Program Files\Sysinternals\procexp.exe"

taskmgr-img-hijack

Now Task Manager is magically Process Explorer.

 


Boot Camp 3.1.3: Cirrus Audio Update

The Boot Camp update for MacBook Pro (13-inch, Mid 2010) (BootCamp_3.1.3_64-bit.exe) contains Cirrus Audio driver 6.6001.1.25 from 4/28/2010 which is newer than the 6.6001.1.21 version from Boot Camp 3.1. This driver works fine in a 2009 MacBook Pro 15-inch except that the package is set up to refuse to install on anything except the aforementioned new MacBook.

I’ve been having a problem with intermittent pops and crackles on my external speakers that seems to be a software/driver issue, so I wanted to give this update a whirl. So far, it seems like 6.6001.1.25 has fixed my pops and crackles problem.

7-Zip can extract the driver from the packaging. It’s just a matter of digging it out. Inside of Boot Camp_3.1.3_64-bit.exe is BootCampUpdate64.msp (a windows installer patch file). 7-Zip can unpack that into some cryptically named directories. Buried in there is a file called Binary.Cirrus_Audio_Bin which is actually some form of archive. Inside of that thing are the driver files.

Once you have Binary.Cirrus_Audio_Bin unpacked, you can point Device Manager at the unpacked location to update your Cirrus Audio driver.

I’m scratching my head a bit, wondering why Apple didn’t generally release this driver to all compatible hardware.

beforeafter

Best Visual Studio 2010 Extension Feature

The coolest Visual Studio 2010 extension feature that I have seen is the Solution Navigator which is a component of the Productivity Power Tools extension.

Solution Navigator combines the Solution Explorer and Class Explorer with search and some useful predefined filters: All, Open, Unsaved and Edited. It’s fantastic for navigating large solutions.

Types Shown in Files

class-all

Filter to Open Files

class-open

Search Types

class-search

Prettify 7-Zip

icons7-zip is a great, free and open source archive utility for Windows. It comes in x86 and x64 flavors with GUI and command-line interface and supports a ton of archive formats.

  • Packing / unpacking: 7z, ZIP, GZIP, BZIP2 and TAR
  • Unpacking only: ARJ, CAB, CHM, CPIO, DEB, DMG, HFS, ISO, LZH, LZMA, MSI, NSIS, RAR, RPM, UDF, WIM, XAR and Z.

Unfortunately, the GUI is not the prettiest and the associated file icons are 32×32 and 16×16 8 and 4 –bit color. Extremely, way retro.

There is a nifty theme manager for 7-zip that scripts Resourcer to replace the icons embedded in the 7-zip executable with new icons of your choice.

There are a ton of filetype and toolbar icon sets in 7-zip Theme Manager but the most complete and consistent pairing is the "Tango 2" toolbar icons with the "Tango 1" filetype icons from the Tango project.

Here’s what the Tango-ized 7-Zip looks like.

tangoized-7zip

%d bloggers like this: