Kanab and the Wave

The recent trip me and Liz took to Utah turned out to be incredible fun. The weather was over 110 most days, and not being 6am starters, we hiked in the heat of the day, but even that was fun in a Man vs Wild way!

Kanab0

We spent our first night camping at Coral Pink Sand Dunes State Park. We were in the middle of a sea of sand dunes, I’d never seen anything like it, especially as the sun was setting. It was an unusual crowd at the camp ground, the park is open for off-road vehicles like dune buggies, so almost everyone else was there for that. It felt very Mad Max! I managed to get a fire lit using flint and steel, after figuring out the knack was to scrape slowly, but with a lot of pressure.

Kanab1  Kanab2
The next day, we went to the Wire Pass trailhead, which involved an eight mile drive down a really bumpy dirt road. From the trail head, we hiked about a mile down the wash until it narrowed, and we entered the slot canyon. This was truly something else, in places it was two feet wide, with sheer walls going up several hundred feet. These are carved out by flash floods, and there’s long sections with no escape route, so we were glad to be out by the time a thunderstorm started in the afternoon!

I highly recommend Michael Kelsey’s book on hiking the Paria River area, which includes lots of fun asides, like stories of murderous Mormons, and rants on the BLM’s permit policy, as well as being the best guide to the trails.

Kanab3 Kanab4 Kanab5

Our trip was inspired by pictures of the Wave, but we knew actually getting to it was a long shot, since only twenty hikers a day are allowed in, and there’s only ten permits available by lottery the day before. We went along to the Paria River BLM office when it opened on Friday morning, and were lucky enough to find someone had just cancelled, and so we were able to go right away!

According to Kelsey, the Wave was popularized by a German film in the 90’s, and sure enough most of the handful of people we met were fellow Europeans. The hike there was only three miles, but was across slick rock most of the way, and only an excellent handout from the BLM and our GPS stopped us losing our way. The weather was hot, around 110, and I got through about 1.5 gallons of water in just a few hours!

The Wave itself was like something from another planet, as you can see from the photos, but the whole hike was full of amazing areas. Even if you can’t get permits to the Wave, I’d recommend hiking outside the restricted area, there’s plenty to see. You get there from the same Wire Pass trailhead as the slot canyon we went to the day before.

Kanab6

Saturday was our last day, so we went for a less taxing hike, to see some rock formations known as the Toadstools. It was only about a 1km hike from where we parked, across a plateau to the edge of some cliffs, but it was hard to find our way. The view across the desert was worth it though.

After that, it was just a simple matter of driving 700 miles back to LA! If you want to see more photos, you can check out Liz’s site.

Writing a BHO installer

Candle
Conceptually, installing an Internet Explorer plugin is very simple. You just have to copy your DLL onto the user’s system, and then add some registry settings so IE will load it. In practice there’s a lot of house-keeping involved to do it nicely, so users can easily uninstall and manage the add-on for example, or to check that the machine meets the minimum requirements. I wanted to use an existing framework that would make that easy, so I did some research.

NSIS was initially very attractive, since I’d used it in the past, and found it fairly user-friendly and robust. It produced a .exe though, and I’ve noticed that .msi packages seem to be a more modern approach, so I looked into alternatives. The most promising was WIX, an open-source system from Microsoft for taking an XML description of what needed to be installed, and turning that into a .msi.

The first hurdle was getting used to WIX‘s declarative approach to installation. The wxs scripts are more like makefiles, in that they declare which files need to be installed, along with conditions and dependencies, rather than asking for a procedural list of steps, as NSIS and more traditional installers do. WIX‘s way makes it easier to repair installations and lets an uninstaller be created from the same script.

I found a great tutorial by Gábor DEÁK JAHN, and pretty quickly I was able to set up a script that copied over my single DLL to a new folder in Program Files. To create an MSI installer, you take a wxs XML script, run the candle command to compile it, and then run light to package it into a .msi.

The really hard bit proved to be working out how to write to the registry. As I discussed earlier, the old way to set up the needed registry information was through a process called self-registration, where code within the DLL would be executed, and that was expected to write to the registry programmatically. These days, that approach is strongly discouraged within an installer, and instead you’re expected to list the registry keys and values you’re altering as part of the script.

This was tough, since PeteSearch relies on ATL to parse a proprietary format called .rgs to set up the required registry keys, and there’s no easy way to translate it to the required wxs XML. I was hopeful that a tool that ships with WIX, called tallow, would capture the registry changes in the right form, but when I ran it with the -s option, it crashed with an exception. This seems to be a known bug, with no solution, so I was left to hand-translate the .rgs file.

Once I got the hang of it, this didn’t take too long. The .rgs file is organized into a hierarchy of keys, each level separated by curly brackets, and at each level multiple keys can be set. Translating meant taking each key/value pair, and turning it into a full <registry> tag in the wix script. For example, this in the .rgs file:

HKCR
{
    PeteSearch.PeteSearch.1 = s ‘PeteSearch Class’
    {
        CLSID = s ‘{00e71626-0bef-11dc-8314-0800200c9a66}’
    }

becomes the following two wix tags:

<Registry
    Id=’PeteSearchReg1′
    Root=’HKCR’
    Key=’PeteSearch.PeteSearch.1′
    Action=’write’
    Type=’string’
    Value=’PeteSearch Class’
/>
<Registry
    Id=’PeteSearchReg2′
    Root=’HKCR’
    Key=’PeteSearch.PeteSearch.1\CLSID’
    Action=’write’
    Type=’string’
    Value='{00e71626-0bef-11dc-8314-0800200c9a66}’
/>

One thing that caught me out was that most of the .rgs entries were writing to the default member of the key, rather than to a named member as I initially assumed. The only one that was different was the ThreadingModel value, which was written to a named member of InprocServer32. The only non-constant value I had to write was the InprocServer32 default, which specifies the location of the dll, which I was able to reference as [INSTALLDIR]PeteSearch.dll

Once I’d converted over the registry settings, I had a functional .msi that would install the dll. The only thing left was to make sure the minimum requirements were checked before the installation went ahead. PeteSearch doesn’t work on anything earlier than Windows 2000, and only runs on IE7,  so after some experimentation I was able to add the following two condition tags as direct children of the <product> tag in my script to enforce that:

    <Property Id="INTERNETEXPLORERVERSION">
          <RegistrySearch Id=’InternetExplorerVersion’ Root=’HKLM’
           Key=’SOFTWARE\Microsoft\Internet Explorer’
           Name=’Version’ Type=’raw’>
          </RegistrySearch>
      </Property>

      <Condition Message=’PeteSearch requires Internet Explorer 7.0 or later ([INTERNETEXPLORERVERSION] found)’>
          <![CDATA[INTERNETEXPLORERVERSION >= "7.0.00000"]]>
      </Condition>
      <Condition Message=’PeteSearch requires Windows 2000 or later’>
          <![CDATA[VersionNT >= 500]]>
      </Condition>

There’s a couple of gotchas I ran into; first the condition text has to be guarded in a CDATA block, or the angle brackets get interpreted as part of the XML. Secondly, when checking the IE version, I had to enclose the constant I was comparing against in quotes, or the comparison always failed.

Putting this all together was enough to create a fully functional installer. The wxs script is available through Sourceforge, or you can download it directly here. There’s no UI apart from a progress dialog, I hope to sort out a basic license and confirmation screen in the future, to give more user feedback, and I’ll cover that when I do.

More posts on porting Firefox add-ons to IE

Ask.com search tips

Asklogo

Ask is one of the most interesting search engines, they’ve put a lot of thought into their UI. They have some cool features, especially after they introduced their new ‘Ask3D’ interface. Here’s how to get the most out of Ask.

More results. Through the display options, you can get up to a hundred results per page, rather than the normal ten. This is really handy if you’re looking for something obscure, and want to quickly do an eyeball scan over a lot of links at once. To turn this on, go to the Options menu in the top right corner of the page, chose Displaying Results, and choose how many you want from the dialog:

Askoptions

Binoculars Preview. Popular sites are given a thumbnail preview you can access by hovering the mouse over the icon next to their name. This is handy for deciding if the site is worth visiting, especially if you’re looking for something visually distinctive.

Askpreview

Search Zooming. For many searches, Ask will provide a list of suggestions to narrow your search, broaden it, and give some names that are related to your terms. This can be very useful when you’re not sure exactly what you’re looking for, it’s an easy way to explore a topic. Suggestions are given on an impressive range of terms, not just the most popular searches. Here’s what I got for optical flow, which is a fairly obscure topic:

Sideoflow

The suggestions given are all relevant to the subject, and very specific. The inclusion of Horn Schunck was particularly surprising to me, showing they’re doing some clever analysis of either the pages they index, or the searches their users make most often.

Modified Since. Ask lets you limit your search results to pages that have changed in a certain time-frame. This helps if you’re looking for information that rapidly goes stale. For example when you hit a bug with a rapidly updating web service like Google Mail, you can check for recent reports of similar problems without worrying about getting high-ranking results that are obsolete. There’s also some searches where you want to narrow your focus, but can’t think of more specific terms. An example of that would be music festivals los angeles. If you were trying to find a particular one you couldn’t remember the name of, but knew was coming up soon, only looking at pages modified in the last week would give you a better chance. This feature comes in handy in the same circumstances that news and blog searches do, for current events and getting the most up-to-date information on things that change rapidly, like fashion. To use it, go to Advanced below the search box, and chose from the Modified Since popup menu.

Askmodified

Sidebar Results. Alongside the main search results, Ask gives you snippets from other services. These vary depending on the search, but they’ll typically contain things like a Wikipedia summary and blog search results. It’s a nice use of space, since the right side is usually unused on other engines, and having it available at a glance makes those areas a lot more accessible. I’m more likely to check Wikipedia or do a blog search if I spot there’s already some interesting results available, rather than having to do an extra searching step without that guarantee.

Wikioflow

Pretty Pictures. My final tip won’t increase your productivity, but it may help your stress levels. On the main search page, there’s an option called skins. On the popup menu, you can choose a background image for the page, Western Sky is my favorite. It’s a nice reminder there’s a world beyond the internet!

More Search Tips…

First PeteSearch IE beta build released

Radioactive
I just completed the installer, and so I’m now releasing the first public build of PeteSearch for IE:
http://petesearch.com/PeteSearchInstall.msi
It requires Windows 2000 or later, and Internet Explorer 7. Please give it a try, and let me know how you get on. I’ve updated the source repository, and I’ll be adding an article on how I built the installer soon.

More posts on porting Firefox add-ons to IE

Registering a BHO

Register

Vlad also asked how a BHO can be added to the registry, outside of the compiler? This is a question I’m wrestling with as I write the installer, so here’s a dump of my current understanding.

There’s three purposes to registration; telling IE that there’s a BHO with a certain ID it should load, telling the system where the DLL is that contains that ID, and what code actually implements the interface we’ve declared.

The first part is covered by the .rgs file in the project. It handles setting up the registry so that our BHO is added to the list of ones to load. If you look at the file, it contains a description of what our DLL contains, including a UUID, and also adds that UUID to the list of BHOs for IE to load. It’s added to the DLL as a resource, and we reference that in our implementation class, by calling the macro DECLARE_REGISTRY_RESOURCEID(<resource ID>) in our class declaration. This adds an UpdateRegistry() member function to our class, that calls an ATL function that parses the rgs script, and adds the keys to the registry.

Telling the system where the DLL lives on disk is handled by calling code inside the DLL itself, in a process called ‘self-registration’. There’s a custom build step that calls regsvr32 /s /c <your dll>. This in turn calls the DllRegisterServer() function inside your dll, which in our case calls a standard ATL _Module.RegisterServer() call. We’ve set up an ‘object map’ containing our UUID, and the actual class that implements that interface, and the ATL call takes that and adds the right information to the registry. This call also adds the DLL location to the registry, and calls the UpdateRegistry() function we set up in our class, that adds the .rgs entries to the registry.

If you want to make this happen outside of Visual Studio, you can call regsvr32 yourself from the command line. Procedural installers like NSIS have script commands that do the same, like RegisterDLL.

As always, there’s a catch. WIX/MSI is a declarative installer, and MS strongly recommends against calling procedural DLL code as part of the process, since that’s a black box to the installation system, and so will be a lot harder to roll back. Instead, I’m going to have to capture a static description of all the registry changes that calling regsvr32 on my DLL causes, and add that to the installation script. Luckily, there’s a tool called tallow that looks like it may help. I shall let you know how I get on!

More posts on porting Firefox add-ons to IE

BHO example for Visual Studio 6

Cow

Vlad Simionescu was kind enough to share a version of the TinyBHO sample he adapted to compile on Visual Studio 6. There’s a couple of changes in the threading model he had to make, that I don’t understand well enough to intelligently comment on, but they seem harmless. It also pops up the URL of the document now, to demonstrate the use of BSTR’s, and some simple DOM access. Thanks for that Vlad!

Download TinyBHO_VS6.zip

More posts on porting Firefox add-ons to IE

Defrag Conference

Defragbuttonpete
I’ve just signed up for Defrag, a conference focused on the implicit web. In their own words:

Defrag is the first conference focused solely on the internet-based tools that transform loads of information into layers of knowledge, and accelerate the “aha” moment.

People often talk about information overload, and trying to cut down the amount of data people have to deal with. That approach leads to solutions where a computer tries to do part of the user’s mental processing for them, which is a slippery slope towards talking paperclips.

I want to give people more information, but in a form they can digest. I want to present something that all our wonderful pattern-matching circuitry can sink its teeth into. We’ve had millions of years of adaption to spotting pumas in the undergrowth, we should take advantage of that.

It feels like a lot of the Defrag folks are thinking along similar lines, so I’m hoping to meet some interesting people who are working at the same coal-face, and get advice and inspiration. Plus I’ve never been to Denver, so maybe me and Liz can combine it with a vacation!