net, vs comments edit

Most of the DXCore/CodeRush plugins I write are Tool Window plugins like CR_Documentor or are plugins you’d bind to a hot key like CR_JoinLines. For Tool Windows, DXCore automatically gives you menu integration…

DXCore Tool Window plugin menu
integration

…and for hot key plugins, you don’t need it. But sometimes your plugin isn’t really a tool window, or maybe you need to integrate into a different menu, like the standard “Tools” menu. I’ll show you how to do that.

Before you begin, consider if you really need this. It’s not hard to add, but if you’re like me, you already have a ton of stuff flooding the various menus. Before you add that to your plugin, determine if you really need to. “With great power comes great responsibility,” right?

OK, so you want the top level integration. Let’s do it.

First, I’ll create a standard plugin project and call it TopLevelMenuDemo. If you already have a plugin project, you can add a new plugin to your existing project. The key here is you need a “standard plugin” rather than a “tool window plugin” for this.

The TopLevelMenuDemo plugin in Solution
Explorer

Next, I’m going to drag an Action onto my plugin designer from the “DXCore” part of my toolbox. I’ll name it “menuAction” so we know what it’s for.

Select the “menuAction” Action and open the Properties window. You need to set…

  • ActionName - Set this to the name of the action. It won’t be visible, but I usually set this to the text I expect to see in the menu.
  • ButtonText - This is the text you’ll actually see in the menu.
  • CommonMenu - This is the top-level menu to which your item should be added.

For our demo integration, we’ll set “ActionName” and “ButtonText” to “Demo Menu Integration” and we’ll set “CommonMenu” to “DevExpress” so we appear in the top-level DevExpress menu.

Properties on the plugin
action.

Switch the Properties menu over to show events and set an Execute event handler. The Execute handler is what happens when someone clicks your menu item.

Events on the plugin
action.

For our demo handler, we’ll just show a quick message box.

private void menuAction_Execute(ExecuteEventArgs ea)
{
  MessageBox.Show("Demo success!");
}

That’s it!

Hit F5 to start debugging. A new instance of Visual Studio will pop up and you should see your menu integration in place.

The plugin menu integration in
action.

Selecting the menu item, you should see the message box pop up. Success!

The demo success message
box.

For the more advanced users… check out the other events you can handle on the action if you want even more control. For example, the PositionMenuButton event can give you more control over the positioning of your menu item within the parent menu. There’s not a lot of documentation out there on this, so you’ll need to experiment a bit, but a lot can be achieved.

net, csharp comments edit

“Guard” classes - those little “convenience wrappers” around common argument checking and exception throwing. You know what I’m talking about, things like…

public static class Guard
{
  public static void AgainstNull(object value, string parameterName)
  {
    if(value == null)
    {
      throw new ArgumentNullException(parameterName);
    }
  }
}

Then, rather than the if/throw block in your method, you have something like…

public void MyMethod(string theParameter)
{
  Guard.AgainstNull(theParameter, "theParameter");
  // Do the rest of the work...
}

It seems like a good idea, right? Reduce the three lines of if/throw checking to a tiny, fluent-looking one-liner. There are some common reasons people seem to like them:

  • Makes the code tighter/more readable.
  • If you want to add common logging, you can do it in one place.

Both are totally legit. But there are a lot more reasons not to like them, and here are mine:

  1. Guard classes defeat static analysis like FxCop. I like FxCop. I treat it like it’s another set of unit tests that help me to make sure my code behaves consistently. I don’t use all the rules, but most of them are valuable. One of those valuable rules can analyze whether you validated an argument for null prior to sending it to another method. If you wrap that check in a Guard class, FxCop isn’t going to see it - it sees the Guard class validating the argument, but not the caller. FxCop can also validate that the name of the parameter in the exception being thrown matches exactly the name of the real parameter on the method - a lifesaver if you’re doing some refactoring that renames parameters and you forget to fix that. You either have to turn these FxCop rules off or write custom rules that understand your Guard class.
  2. Guard classes become giant validation dumping grounds. How many things can you imagine you need to Guard against? Null values, sure. Maybe strings that are null or empty. Collections that are null or empty. How about ranges? Things like “if this date is in the future?” What else? There are actually a lot of things you can possibly guard against. Unfortunately, unless you’re in a very small team, that means the Guard class quickly becomes hundreds of lines of code doing dozens of different validations that aren’t actually all that common, and there’s no real way to “draw the line” and say “this should be in, but this shouldn’t.”
  3. Guard classes mess up the call stack. The place where the exception gets thrown is now no longer actually the method that should be doing the validation - it’s one level deeper (possibly more if you call Guard methods from other Guard methods).
  4. Guard classes become a single point of failure. Someone messes up or tweaks the logic in one Guard check, that affects literally every method through the whole application. It also means you’d better check performance well in there because it’s totally central.
  5. Guard classes tend to get used in the wrong places. Say you have a check that validates for null, as seen in the example above. That’s great for validating arguments to a method… but what about if you read in a configuration value and you want to check it for null. Same Guard method? No! The configuration value isn’t an argument, so you shouldn’t throw an ArgumentNullException. Unfortunately, it’s very tempting to go shorthand everywhere and end up throwing the wrong exceptions just because it’s convenient.
  6. Guard classes fool your unit test coverage. If you ship the validation of arguments or values off to a Guard class, then suddenly your unit test coverage is 100% whether or not you test the failure scenario of an invalid argument - it passed through the Guard class, so that line got covered. Done! Unless you’re doing strict TDD where you wrote the negative checks up front along with the positive checks, there’s going to be a pretty good chance you’ll forget to add all the negative test cases… and there’s no way to tell if you did or not.

I’m not convinced that saving one (or three, pending on your counting) lines of code for an argument check is really worth all the downsides.

net, build comments edit

When building a Sandcastle Help File Builder (SHFB) project in the GUI, you manually specify the list of assemblies you want to document. However, if you want to make the execution of it a little more flexible, you can do a bit of MSBuild magic to dynamically build up the list of documentation sources for the project prior to execution.

The reason this works is that SHFB has changed its command-line execution to run through MSBuild using build tasks rather than a standalone executable. (Though with the executable, you could go through some steps to fashion a response file, you can skip the temporary file creation now.)

First, create your SHFB project in the GUI. Set up all the various settings including a few assemblies and make sure it builds the documentation properly.

Next, run the SHFB build from the command line. SHFB projects are MSBuild projects now, so you can run them through MSBuild at a Visual Studio command prompt:

MSBuild Documentation.shfbproj

This establishes that everything is working properly from the command line. You’ll need that because when you make the project dynamic, you’ll have to run it from the command line.

Create a new MSBuild project file that you will use to dynamically build the list of documentation sources (assemblies/XML files) and add a target in it that will run the SHFB project.

If you are using SHFB 1.9.3.0 from .NET 4.0, you can use the MSBuild task directly, like this:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <Target Name="Build">
    <MSBuild ToolsVersion="4.0" Projects="Documentation.shfbproj" />
  </Target>
</Project>

On the other hand, if you’re using SHFB 1.9.1.0 from .NET 4.0, you’ll need to use the Exec task to run a .NET 3.5 MSBuild process manually, like this:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <Target Name="Build">
    <!--
      You have to use MSBuild 3.5 with SHFB or you get a warning
      telling you that any parameters you pass will be ignored.
    -->
    <Exec
      Command="&quot;$(windir)\Microsoft.NET\Framework\v3.5\MSBuild.exe&quot; Documentation.shfbproj"
      WorkingDirectory="$(MSBuildProjectDirectory)" />
  </Target>
</Project>

Execute your new MSBuild project and make sure the documentation still builds.

Open up the SHFB project in a text editor and find the DocumentationSources XML node. This is the bit that we’re going to make dynamic. The node in question looks like this:

<DocumentationSources>
  <DocumentationSource sourceFile="..\build_output\bin\Assembly1.dll" />
  <DocumentationSource sourceFile="..\build_output\bin\Assembly1.xml" />
  <DocumentationSource sourceFile="..\build_output\bin\Assembly2.dll" />
  <DocumentationSource sourceFile="..\build_output\bin\Assembly2.xml" />
</DocumentationSources>

The tricky part here is that DocumentationSources is a property, not an item, so when you make this value dynamic you actually need to build an XML string, not a list of files like you would for other tasks.

Remove the DocumentationSources node from the SHFB project file (or comment it out). We’ll be building that dynamically and passing it in as a parameter.

In your new MSBuild project file, use an ItemGroup to locate all of the .dll and .xml files that should be included in your documentation. These are the files you will have seen in the list of DocumentationSources:

<ItemGroup>
  <DocTarget Include="..\build_output\bin\*.dll;..\build_output\bin\*.xml;" />
</ItemGroup>

Use the CreateProperty task to build the XML string that contains each DocumentationSource node:

<CreateProperty Value="@(DocTarget -> '&lt;DocumentationSource sourceFile=%27%(FullPath)%27 /&gt;', '')">
  <Output TaskParameter="Value" PropertyName="DocumentationSources" />
</CreateProperty>

Finally, pass the list of DocumentationSources to the SHFB project when you run it.

If you’re using the MSBuild task:

<MSBuild
  ToolsVersion="4.0"
  Projects="Documentation.shfbproj"
  Properties="DocumentationSources=$(DocumentationSources)" />

If you’re using the Exec task:

<Exec
  Command="&quot;$(windir)\Microsoft.NET\Framework\v3.5\MSBuild.exe&quot; Documentation.shfbproj /p:DocumentationSources=&quot;$(DocumentationSources)&quot;"
  WorkingDirectory="$(MSBuildProjectDirectory)" />

A complete MSBuild script that uses SHFB 1.9.3.0 and the MSBuild task looks like this:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <Target Name="Build">
    <ItemGroup>
      <DocTarget Include="..\build_output\bin\*.dll;..\build_output\bin\*.xml;" />
    </ItemGroup>
    <CreateProperty Value="@(DocTarget -> '&lt;DocumentationSource sourceFile=%27%(FullPath)%27 /&gt;', '')">
      <Output TaskParameter="Value" PropertyName="DocumentationSources" />
    </CreateProperty>
    <MSBuild
      ToolsVersion="4.0"
      Projects="Documentation.shfbproj"
      Properties="DocumentationSources=$(DocumentationSources)" />
  </Target>
</Project>

Done! A dynamic Sandcastle Help File Builder project that you’ll never have to update as you add or change the assemblies you want documented.

web, gists, windows comments edit

I run in Windows as a non-admin user. Whenever I need to install something and Windows prompts for credentials, I have a whole separate user account that runs admin tasks.

This appears to be a problem for the automated Firefox software update process. What I run into goes something like this:

  1. Open Firefox and get notified there’s a software update.
  2. Click the button to close Firefox and apply the update.
  3. Firefox closes and prompts me for admin credentials, which I provide.
  4. The update installs, Firefox restarts, and then notifies me there is a software update.

What seems to be happening is that Firefox downloads the update for my non-admin user account, then when I provide admin credentials it re-downloads the update under that admin user account. After the update is done, Firefox still sees a pending update for my non-admin user account and wants me to apply it.

This happens with every update to the Firefox browser. Add-ons seem to update just fine, but the browser just can’t handle it.

Of course, if I try to apply the update with my non-admin user account, Firefox closes and re-opens without applying anything. Then it sees the pending update and wants to fake-apply it again.

The solution is to manually reset the automated Firefox software updater by removing all of the pending updates from the download cache.

Per this Mozillazine article, to do this:

  1. **Close Firefox. **
  2. Open the temporary application data folder for Firefox. In Windows Vista and above, this is: C:\Users\your-username-here\AppData\Local\Mozilla\Firefox\Mozilla Firefox

  3. Inside that folder, you’ll see a folder called “updates” and two files “active-update.xml” and “updates.xml” - delete the “updates” folder and the two XML files.

Aaaand… DONE. Next time you open Firefox it will do its automated check for updates and apply as necessary.

UPDATE: Here’s a batch file that does it on Windows 7 and Windows 2008.

@echo off
del "%localappdata%\Mozilla\Firefox\Mozilla Firefox\active-update.xml"
del "%localappdata%\Mozilla\Firefox\Mozilla Firefox\updates.xml"
rmdir /s /q "%localappdata%\Mozilla\Firefox\Mozilla Firefox\updates"

media comments edit

I have a lot of DVDs and they get stored in binders, but I don’t have so many Blu-ray discs and I like to keep them separate from the DVDs. I don’t rip the Blu-rays to my movie server, so it’s good to have them a little more accessible.

I had previously been storing them on a shelf like books in a library, but the shelf is out of space and things are looking bad. Time to find something else.

Trucking around The Container Store I found these DiscSox HiDef Pro Sleeves that are the perfect solution.

DiscSox HiDef Pro Sleeves and rack. Click to
enlarge.

These sleeves allow you to store two discs per sleeve and the cover is actually the cover from the Blu-ray case, so it’s a nice browsing experience. For the fewer-than-65 Blu-ray discs I have, this is great. Recommended.