Setting $home in PowerShell

Lately I’ve been getting acquainted with Windows PowerShell, which is something Windows has needed for a long time.  Finally, there’s a real shell for Windows that supports scripting in a format other than horrific batch files.

At work, for whatever reason the powers that be have set our %HOMEDRIVE% and %HOMEPATH% environment variables to a networked drive.  This would be a good idea, but the problem is this drive has a pretty low quota applied and I managed to fill it up within a week or so.  Basically, people use it as a convenient public share directory.  I mention this because changing the environment variables in this way has caused me much grief.  cmd.exe defaults to %HOMEDRIVE%\%HOMEPATH% when it starts, so every time I open a command prompt I end up in this stupid useless directory.  PowerShell is not immune to this either.

I noticed that my PowerShell always started here and that the $home variable seemed set to it as well.  I set up a profile to change my location to the correct place, but had trouble setting the value of the $home variable since it is read-only (or constant, according to the error message).  Luckily, there’s a way to tell PowerShell, "I know what I’m doing." and the Set-Variable cmdlet takes a -force parameter.  So in the end, my script ended up looking something like this:

Set-Location "C:\Documents and Settings\username\My Documents"
Set-Variable -name home -value "C:\Documents and Settings\username\My Documents" -force

I could probably make this more OS-agnostic by using the .NET Environment class, but that’s a project for another day.

Why doesn’t Subversion add respect svn:ignore?

I use Subversion for source control on my personal projects, and I’ve got to say it’s so easy to set up and use there’s no excuse for not using source control.  There’s one thing that really bothers me though.

When setting up a .NET project, I have a few steps I have to follow due to the small clashes with the default project templates I have.  I have to rearrange a few files after VS creates the project, then I get to adding files.  One of the first things I do is set up svn:ignore on each directory; I want it to ignore *.suo, *.user, bin, obj, and occasionally a few other files/directories.  Every time I do this, I double-check with svn status to make sure that nothing I don’t want is showing up, then I feel like it’s safe to do svn add directory.  I mean, I told svn I’d like to ignore those files, right? so it should ignore them, right?  Wrong.

So, for every project, I have to either add every file then use "svn delete –force" to remove just the files that I told it to ignore in the first place, or I have to manually add every file and directory in my project, being careful not to add anything that I’m ignoring.  This is frustrating, to say the least.  At first, I thought it was because the directory wasn’t yet under source control or the svn:ignore setting hadn’t been committed, but I’ve tried committing all directories and property changes first to no avail.

The part of it that’s most aggravating is the fact that "svn add" has a –no-ignore argument; what on Earth is it there for if the command already disregards svn:ignore?  I hope I’m just missing something stupid; I’m going dig around the internet and see what I can find.

*update* According to a blog I found, it has to do with the OS doing wildcard expansion, not Subversion.  That actually makes a lot of sense, because the OS has no idea about svn:ignore.  Apparently the default add behavior is to act as if –noignore is specified (which seems dumb to me), so when you pass it a list of files it just adds all of them.  The solution?  Set up the ignore traits on the directory, then use "svn add –force ."  I have no idea why the –force is required.  It looks like this got added to the SVN book very recently.

Inheriting from ReadOnlyObservableCollection<T> and a Lesson about Constructors

I had need of returning a bindable collection from one of my classes, but didn’t want to allow the caller to modify the collection.  This generally requires a straightforward pattern in .NET: make a SomethingCollection class that derives from Collection<T> and a ReadOnlySomethingCollection class that derives from ReadOnlyCollection<T>, then only return the read-only version.  Most examples don’t bother with declaring the derived types, but I feel like it makes everything look better and the framework classes seem to favor declaring their own collection types as well.

I was having one heck of a time getting everything to work. I tried the most basic implementation:

public class ReadOnlySomethingCollection : ReadOnlyObservableCollection
{
}

This failed miserably with a fairly archaic error message:

‘full typename’ does not contain a constructor that takes ‘0’ arguments

I struggled with this for a while. The error message was clearly correct; if you walk the inheritance tree there’s no base class that defines a parameterless constructor. Still, defining a constructor that matched the signature of the 1-parameter constructor didn’t seem to be solving the problem. I decided it’d be best to step outside my project and make a simple example project in preparation for asking forums and newsgroups what was going on. It turns out switching languages to VB .NET was a good idea, too, because its error message was much more helpful once I had the constructor in place:

First statement of this ‘Sub New’ must be a call to ‘MyBase.New’ or ‘MyClass.New’ becasue base class ‘…’ does not have an accessible ‘Sub New’ that can be called with no arguments.

I saw this, thought about it for a minute, then had a forehead-slap moment. When a class derives from another, it’s almost as if you have two objects glued together. The base class has to be initialized before the derived class can be initialized, because the derived class’s constructor must be able to assume its base members are in a good state. So, in my case, the compiler was trying to initialize a ReadOnlyObservableCollection<T>, but since there was no parameterless constructor it couldn’t. The solution was to do exactly what VB said: make sure I call some base-class constructor as my first action. I finally got it to work in C#:

public class ReadOnlySomethingCollection : ReadOnlyObservableCollection
{
    public ReadOnlySomethingCollection(ObservableCollection list) : base(list)
    {
    }
}

This isn’t the first time that it’s taken VB error messages for me to understand the solution to my problem; I wish there was more consistency between the error messages.

More IDE Omissions

This one was enough to warrant an adventure in continuity.

I’m making an application in WPF to get a feel for how some of the technology works, since so far I’ve been using it in little sandbox applications.  I got all my data classes made and decided it was time to make the UI.  I want to make a dialog, so I figure it’s like how I’d do it in Windows Forms: "Right-click project>>Add Window", right?  Wrong.

I can add a Windows Form from the right-click menu.  If I just go to "Add>>New Item…", I can add a WPF User Control, but apparently no one thought you’d want more than one Window per project.  I believe the right-click menu issue is because I’m not using an Application Definition but a Main method to kick off my application.  It’s still aggravating.  Once again, the IDE is punishing me because my approach to application architecture isn’t what VS considers the "right" way.  Now I have to manually add a XAML file (as an XML file, then rename it and add the Window element manually) and a code-behind file, making sure that I get the x:Class attribute right and import the correct namespaces.  Tell my why we paid for an IDE again?

IDEs considered harmful?

Jeff Putz mentions a post about a person who switched from an IDE to a text editor and why it isn’t such a good idea.  I’m not sure where I stand.

On the one hand, there’s no denying the utility of features like Intellisense and integrated debugger support that he mentions.  I would argue that several "text editors" these days support such features, but I will concede that many of them fall short of a really good experience.

On the other hand, I can also agree with many of Charles Petzold‘s points.  When you use Visual Studio, it forces you to structure your programs in a specific way.  I’ll discuss the hiding of designer code and the lackluster support for WPF file types and why I believe they exemplify a case where an IDE hurts users as opposed to a text editor.

Starting with VS 2005, designer code is hidden away in partial classes.  In C#, you are more aware of this because the designer files are displayed along with a separate code file, so it’s clear you’re working on a class spread across several files.  In VB .NET, VS pretends like there’s only one file, and since the user can’t see any evidence of designer code one can assume the designer works by magic. One of the main reasons I see cited for this is so the user doesn’t accidentally edit code in a location that’s subject to be modified at the designer’s leisure.  There’s really no way to force the designer code into the main class, but it does seem like if you open a file that already has designer code in it, then the designer does the right thing and doesn’t insist you create a partial class. 

I care about this because no programmer should ever believe the tools she uses are magic, and forcing the designer code to be hidden enforces this belief, particularly among VB users.  I’m very active on a VB .NET programming forum, and I generally see one or two questions a month that either directly ask for information about dynamically creating controls or for which the most elegant solution is dynamically creating controls.  More often than not, the poster is completely ignorant of the fact that the VS designer generates code that they could write themselves; sometimes they literally state, "How do I programmatically invoke the designer so I can put some buttons on the form?"  Reading through one of Charles Petzold’s books on .NET is a good way to avoid this if you’re a .NET newbie: Petzold tends to start in the code and discourages you from using the designer until you understand what the designer does for you.  I wish more beginning programming texts would start this way; the designer-first approach seems to produce programmers that believe there’s a drag-and-drop solution to every problem, and anything without such a solution is not possible. 

I don’t argue that there shouldn’t be a designer, but I do argue that the designer code shouldn’t be so well-hidden from the user.  I learned how to use several controls by configuring them with the designer, then looking at the code that was generated in VS2003; it’s a shame that many people don’t even know this is possible.  What’s interesting is in WPF, you pretty much have no choice but to write code for your layout whether it’s XAML or imperative code, so it seems perhaps this evil practice will fade away.

The next thing I want to discuss is the lackluster support for WPF file types in VS 2008.  How do you think I create a loose XAML file in WPF?  The use case isn’t necessarily uncommon; suppose I want to create a window and I don’t need a code-behind file, or I want multiple themes for a custom control.  I have two choices: I can create a WPF window and delete the code-behind file and edit the XAML file to be what I want, or I can create a new XML file, name it with the XAML extension, and remove the XML document declaration.  There’s no way to add just a loose XAML file, even though it’s a fairly common need.  I feel like this can lead a new WPF developer to believing silly maxims like, "All Windows must have a XAML and code-behind file". 

So while I agree that an IDE can provide utility to a programmer, I also feel that the more code your IDE writes for you or the more templates you use then the more your architecture will be dictated by the tools you use, rather than the needs of your application.  I don’t suggest a wholesale switch to text editors, but I do feel like if you can’t use a text editor to write your code then you aren’t familiar enough with your language. 

Programmatically Creating Windows File Associations

A user on the VB Development Forum I’ve visited for a few years asked a question about creating file associations.  I chuckled and assumed that a Google search would return a wealth of information about the subject.  I was wrong; by my fifth combination of search terms I had found one site that had the minimal steps to get it done, and it wasn’t even correct.  The rest of the results were happy to discuss using the File Types tab of the Folder Options dialog to accomplish the task; this is not programmatic and not what the user wanted.  I remembered having a heck of a time trying to figure out how to make an association for all files (so I could have a right-click->Edit with hex editor option) so I decided I’d write up what I know.  Shame on you, internet, for letting the information get buried.

To start off, my example is technically incorrect.  I’m working with HKCR, but apparently the content here is generated based off of HKCU\Software and HKLM\Software. I assume this is so you can have per-user and global associations; I wrote my example using HKCR directly but you should probably use one of these two; please understand when I say HKCR I mean one of the other two locations.

I found the File Associations documentation, but haven’t had time to look over it properly.  For now, this should do.  In order to make it so that when you double-click a file your application opens you need three things:

  1. Your application should support opening a file from the command-line in some way.
  2. You need a registry key to associate a file type with the extension.
  3. You need a registry key to associate a program with the file type.

The first one is up to you; I can’t tell you how to do it.  The registry key to associate a file type with an extension is pretty easy.  File extensions are listed in HKCR under keys named after the extension (including the period!) The value of these keys is a string that defines the file type associated with the extension.  I tend to not use spaces in these, but I have no idea if spaces are unsupported; it will end up being the name of a subkey later and I’m too lazy to check if spaces are supported in subkey names.  For example, text files have the extension txt, and the key that specifies the file type is HKCR\.txt.  It’s default value is txtfile.

Now that there’s a file type associated with the extension, you need a registry key that tells the shell how to handle operations on the file type.  There’s lots of things to implement here, but I only know the basics.  File types are declared in subkeys of HKCR named after the file type; their subkeys and default values vary based on exactly how the file type is to be handled.  All I’m going to discuss is handling the "open" verb, which is generally invoked by double-clicking a file in the shell.  To add support for this verb, a tree of subkeys need to be created under HKCR\filetype. Working with our Notepad example above, we see HKCR\txtfile\shell\open\command.  It has a value that represents the path to Notepad and the replacement string %1 for the file that was selected.

Example time

Suppose we want to associate Notepad with the file extension .zzz.  We’ll start by defining a key for the file type:

HKCR\.zzz
Value="MyEditorFile"

Now, we create the file type key and associate the "Open" verb with notepad:

HKCR\MyEditorFile\open\shell\command
Value="%SystemRoot%\system32\NOTEPAD.EXE %1"

Note that though there are no quotes in the value for the open key, I’ve had trouble in the past when this string didn’t have anything that could possibly contain a space quoted. For example, I’m used to using:
"C:\Program Files\My Program\program.exe" "%1"
I’m not sure why Notepad’s special and doesn’t require this.   That’s really all I have to say on this topic for now; I am still looking over the documentation.

FolderShare is Almost a Good Idea

I was taking a look at the Windows Live FolderShare beta, and it seemed to be exactly what I wanted.  I have a few forum reply templates and AutoHotkey macros that I could use both at home and work, and using a USB drive to keep them in sync just feels kind of lame in this age of internet connectivity.

I uninstalled it after using it for 10 seconds.  All I want out of the program is to share the particular folders that I tell it to share.  Instead, the program gives access to every drive on connected machines; the purpose of libraries is to specify what folders you want to keep in sync.

This makes use of the program unacceptable at work; I like to think my passwords are secure but running FolderShare means if my account is cracked then the source files on my hard drive are exposed.  Unacceptable.

Why couldn’t they resist sharing every single folder?  Why couldn’t they at least let me configure whether I want to allow this from the machine?  The only other tool I know of is DropBox, and it’s in private beta so I can’t try it out.  I wonder if there’s any other solutions, or if I could whip up something quick in .NET that does it?

Getting Soft Word Wrap in gVim and Emacs

I really don’t like most Windows text editors.  I use gVim for all of my text editing.  Everyone extols the virtues of Notepad++ and several other text editors, but they miss some basic features that really make text editing a lot more fun.  gVim lets me move around the file word-for-word without nasty Ctrl+this or that combos that require me to put my hands all over the keyboard.  I can get to very specific parts of a text file very quickly with gVim, whereas all Windows text editors force me to use the mouse.  gVim has the added bonus that it’s really rare to find a *NIX system without it, so I’m able to happily edit text on any machine.

The one thing Windows text editors always get right that I could never get gVim to do is soft word wrapping.  Notepad does this perfectly (so do web input controls.)  When you hit the end of the line, the text wraps to the next line, but when Notepad saves the file, all of the text is on one line.  gVim uses hard word wrapping by default: When you hit the end of the line in gVim, one of three things happens based on your word-wrapping options:

  1. The text scrolls and you’re in horizontal scroll unhappyland.
  2. gVim happily inserts a hard line break into your file.
  3. gVim wraps the text, but leaves a marker to indicate that this is a logical line rather than a physical line.

I hate #1.  I want to be able to see all the text in the file except in very rare circumstances.  #2 sucks when I’m writing something that’s ultimately bound for another program with no facilities for saving, like our issue tracking software; it really stinks
when all of your text has unnatural breaks because
the character width of the editor is nowhere near
as big as the web page.

This leaves #3 as the setting I use most frequently.  This gets annoying for scrolling though; my mind wants to jump from the "first" line to the "second", but this is a horizontal operation rather than the vertical operation that the display suggests.  It always takes me several tries.  I tried for a long time to find ways to get soft word wrapping in gVim, but decided it was impossible and started down the dark path of Emacs (which is actually pretty cool, but I still like gVim better!)

I found that Emacs performed much like gVim, but the way it did its wrapping like situation #3 was much more tolerable.  Still, I wanted things to work like in Notepad.  I found a blog post about enabling soft word wrapping in Emacs (M-x longlines), and it worked like a charm.  Still, I had a lot of muscle memory invested in gVim, so I decided to give it one last Google search.  gVim tip #989 is enabling word wrap without line breaks, which works like a charm.

I’m still kicking around the idea of converting to Emacs, though.  I like gVim’s "your hands shouldn’t leave the home row" philosophy, but it really seems like Emacs has better support for things like HTML and XML.

Snarky Comment of the $timeperiod

I read Jeff Atwood’s Coding Horror as frequently as he posts material.  Like many blogs, the true entertainment value comes from the comments.  I saw this one today:

$40 for SmartFtp. $40 for Winzip. Multiply by all the small tools you need. I won’t even begin to get to get into real development tools like Visual Studio. Windows developers seem to be made of money. One of the reasons I got out of the Windows world a decade ago was the cash I was shelling out just to stay current.

I’m particularly fond of the "Windows developers seem to be made of money" part.  It expresses surprise that somehow, people who develop on Windows have a lot of money to spend on tools.  The viewpoint of astonishment implies that, as a non-Windows developer, the writer does not have very much money and is curious why people who develop for Windows have more money than he does.  Hmmm…

I’m not implying there’s more money to be made on either side of the war, just that I wish people weren’t stupid about their jabs at the other side.  There’s tons of free FTP utilities for Windows; one was mentioned in the very post this user commented on.  I haven’t used Winzip for at least 5 years because the zip support built into Windows is adequate for me, and 7-zip is useful for when I encounter a file that’s not a zip file for whatever reason.  Visual Studio is a nicety but SharpDevelop is just fine and free; a decent coder should be able to get by with Notepad in emergencies anyway.  The poster’s main points are:

  1. All Windows development tools cost money.
  2. Windows developers can afford the tools because they have a lot of money compared to non-Windows developers.

The first one is false.  The second depends on your definition of "a lot" and "Windows developer", but doesn’t do much to encourage me to hug a Penguin in the near future.

Consumer Satisfaction

I want to pat Activision support on the back since I complained yesterday.  I emailed their tech support with my problem and was told I’d get a response within two business days.  I pretty much expected this to mean 3 weeks or so.  They answered within 6 hours on a weekend.  I am very pleased with this experience.  If anyone from Activision reads this, you have my compliments on your tech support.

I don’t think it’s the disc anymore because after letting everything sit for a few hours I’m not having any problems with the game.  I’m thinking my Wii’s on the fritz and maybe it needs a cleaning.  I wonder if there’s even a cleaning kit for the Wii?

The game itself is pretty cool.  The reviews seem to complain that it doesn’t bring very much new to the GH series, but that leads me to ask what exactly new we need.  I bought it to play a rhythm and timing game that plays rock music, and this is what the game delivers.  I fail to see how you could be disappointed.