Possible Possum

Possum

Actually, a probable possum. The cats alerted us to something sneaking around the woodpile last night, and it turned out to a giant-rat-like critter. After our initial hopes of an ROUS, some poking around in google images lead us to the possum hypothesis.

As well as giving me the chance to say ‘possum’ a lot, which is a treat in itself, it was also another in the list of cool American critters I’ve been lucky enough to see. It joins coyotes, tarantulas, scorpions, bobcats, rattle snakes, king snakes, racoons and black widow spiders. The black widows are also prone to hanging around our house, which adds a certain edge of danger to walking to the hot tub at night!

If you want to see more nature in LA, a good place to start is the Santa Monica Mountains Trails Council. Liz sits on their board, and maintains the website, including a trail and plant of the month.

How to promote your add-on – The Message

Message
The previous two posts were about the mechanics of how to contact potential users of your add-on. I’m now going to cover a much fuzzier problem, how to persuade them to consider using it once you are in their field of view. This is an area I need to improve on for PeteSearch, so a lot of it will be practical examples of how I’m trying to change things to be more persuasive.

I met with Mrinal Desai over coffee last week. He’s the chief evangelist for the wonderful Crossloop, and he’s done an amazing job with the app. From being unknown less than a year ago, it’s now got thousands of users all over the world almost entirely through blogs, digg, and other word-of-mouth marketing. They recently crossed the three million user-minutes mark! So, he’s somebody whose advice I value.

He asked a pretty simple question; "What is PeteSearch for?" My immediate response was ‘to make search better’, but this didn’t feel concrete enough, even to me. It reminded me of Guy Kawasaki’s advice from The Art of the Start, to have a three word mantra that describes the difference you’re trying to make to people’s lives. Once you have that, it’s the start of both a coherent, understandable marketing message, and a test for decisions you make about the product.

You may think you don’t have a marketing message, but everything from the name of your add-on, to its description on distribution sites, to its home website, is material that people use to make a decision about using it. The fundamental question you need to answer is "What does it do for me?", how will it improve your potential user’s life? Your answer to this should be your mantra, and everything else should build a convincing case to persuade a user that it does solve their problem.

As a practical example, PeteSearch is trying to improve search, but no user wakes up in the morning and thinks "I need improved search". Users have much more concrete gripes; "I wish I didn’t get so many 404 links when I searched", "It’s annoying to go back and forth between the search and result links all the time", "Why is the text summary so short?", "I wish I could use the keyboard to navigate through results, rather than the mouse". At the moment the add-on is trying to solve all these problems at once, and they’re all equally prominent in the marketing.

This is a problem, because a single user is unlikely to have all these gripes at once, so most of what they read in the marketing is solutions to problems they don’t have. Even a lot of the UI in the extension itself ends up being clutter. This attempt to solve everyone’s problems actually ends up solving nobody’s.

To fix this, I’ve decided my mantra will be "Better Search UI", and I will focus like a laser on adding great keyboard navigation to Google. This will make describing it a lot simpler. I’m even considering a name change to GoogleHotKeys, to make it a lot clearer to potential users what’s in it for them.

PeteSearch may be unusual, many add-ons are built with a much clearer, specific need in mind, but if you’re struggling with a your site or description, I found starting with a mantra really helped me to improve my message.

More posts on add-on promotion.

How to promote your add-on – Distribution

Scatter

Getting your extension distributed on sites such as addons.mozilla.org or Windows Marketplace will help you find an audience in several ways.

Discovery. People who are interested in finding new add-ons browse these sites. You’ll be in front of an audience of early-adopters who are interested in experimenting. This can be very powerful if you’re trying to solve a problem that applies to a lot of people, rather than a more niche issue. Most people won’t invest the time to try your plugin unless it’s offering a solution to a specific and painful problem, but this audience is curious and more willing to take a chance.

Legitimacy. Nobody’s heard of you. Unless you’re a big company or celebrity, or you’re targeting a niche audience in an area where you are well-known, you’re a stranger who wants to install software on their computer. This sets a very high trust barrier to overcome! Distribution sites effectively lend their sponsor’s reputation to your add-on, making people feel comfortable installing the add-on because they know the sponsor has a lot to lose if they do distribute something malicious. To protect their reputation, the sites generally have a vetting process to check add-ons before they’re allowed on the site.

Promotion. Distribution sites exist to show off all the cool extensions that exist, and are generally set up by the creators of the main app. Having a good collection of add-ons is an important selling point for the browsers, and so some extensions are included in their established marketing efforts. If your add-on gets picked as a great example, and prominently featured in their marketing, you’ll reach a lot of people. This will usually happen after you’re an established add-on, with proof that you appeal to a large audience already, so don’t make any plans that rely on this, but it’s a great bonus if it does happen.

So, getting on a distribution site is a good idea. How do you do it? For PeteSearch, I’ve only made it onto the Firefox site so far, so I’ll focus on that process, but I’ll be attempting to get the IE conversion up on Windows Marketplace soon, I’ll cover the practicalities of their vetting process once I have.

To get started with Firefox, go to their addons site and register as a new user. Once you’re registered, you can then upload the extension you’ve created. You’ll need to provide information about it, and some basic checking will be done when you upload the file, to make sure it supports the correct versions of Firefox for example. Once you’ve got it uploaded, you then chose to make it publicly visible. This places it into the sandbox, which is a sort of purgatory for plugins, where they wait to be approved. They are only visible to people who create mozilla accounts, and change their account options to make sandbox add-ons appear. The idea is to distribute the approval process by getting reviews from people who browse the sandbox, so that the final mozilla reviewers have something to base a decision on. In practice, very few add-ons receive reviews in the sandbox, I’m assuming because very few people are browsing it.

Since an add-on with no reviews will be rejected if you nominate it for the public site, this can be a problem. For PeteSearch, I was able to work around this by gathering links to all of the external reviews, and including them with my developer notes, after it was rejected the first time.

More posts on add-on promotion.

How to promote your add-on – External Blogs

Megaphone

So, you’ve written an IE or Firefox extension. Now, you need to tell people about it! In this new series, I’ll be covering what I’ve learnt going through that process.

External blogs. A lot of my users have come from four main-stream blogs who I contacted directly about PeteSearch; John Batelle’s SearchBlog, Gary Price’s ResourceShelf, WebWorkerDaily and Hackszine, but I’ve also had some good traffic from blogs who discovered it themselves, like Pete Prestino’s, BrainsFeed and NetWizz.

I would recommend finding authors who’ve written about the problem you’re trying to solve, and emailing them, or leaving a comment on a relevant article. Invest some time on their site, try to contribute to their community, and get a feel for the readership’s needs. Be very respectful of their time, they are all dealing with a lot of unsolicited emails, so be clear and concise on what your extension offers. That way they can quickly decide if it’s something their readers may be interested in.

Don’t be offended if you don’t hear back, expect the majority of your attempts to reach out to have no response. If they do reply, or post on their site, make sure that you thank them with an email!

Treasure any feedback you get, especially the negative. Remember, almost all people will silently stop using your addon if there’s a problem with it, so someone who tells you why it sucks is doing you a big favor!

More posts on add-on promotion.

Refresh and DISPID_DOCUMENTCOMPLETE

Waterfall

One of the great unsolved mysteries of BHOs is how to catch refresh events. When the user refreshes a page, DISPID_DOCUMENTCOMPLETE and DISPID_NAVIGATECOMPLETE are not sent, as they are with a normal load. Add-ons rely on that to know when they can start changing the DOM, so it’s a pretty serious problem.

There are some suggested solutions that use the DISPID_DOWNLOADCOMPLETE event, which is sent on a refresh, but only after all images have been downloaded. Since you get one of those for every document complete, you can do some jiggery-pokery to spot if you get one of those without a corresponding navigate complete to spot refreshes.

It seemed like there had to be a more reliable way than this, so I’ve cooked up a solution that detects refresh events directly. You can download example source code here.

It works by attaching a hook to IE’s main window procedure using
SetWindowsHookEx(WH_CALLWNDPROCRET, …);
This calls back to the function we specify, after every call to IE’s message loop. By looking at what happened during a refresh, I spotted that a WM_COMMAND message is always passed, with a LOWORD(wparam) of 0x1799 for a refresh caused by pressing F50xa220 for one triggered from the main menu, and 0x179a for the context menu. These values are consistent across both IE 6 and 7.

I’ve set up my hook function to get called after the app’s message handler, so when I see a refresh command has just gone through, I override the default refresh behavior by explicitly calling IWebBrowser2::Navigate() to the current page’s URL. This causes IE to go through the normal loading events, so BHO’s now receive the usual document complete call.

Here’s the pros and cons of this new approach:

Pros:

Simplicity. Compared to the book-keeping needed for the event counting approach, it’s a lot easier to code.
Identical to normal loading. A refresh now triggers exactly the same page-loading events as loading a new page.
Right time. The event counting approach only detects a refresh when it sees a download complete event, which can be some time after the document is actually ready.

Cons:
Voodoo-esque. Relying on details of IE’s internal implementation is risky. The fact that it’s been consistent for several years makes it less scary.

Redundancy. If more BHOs use this approach, you could have the code called multiple
times for a single refresh. In practice this doesn’t seem to cause any noticeable problems.
Misses script refreshes. If a script calls window.location.Reload(), this won’t be detected.
Subverts
IE’s refresh behavior
. This is probably the most serious issue, since I
know there’s multiple meanings for refresh, depending on whether shift
is held down, etc. In production code, I’ll probably limit the forced
reload to pages where I needed it (eg search results for PeteSearch)

Overall, this seems better than the alternatives for my purposes. I’d prefer to avoid the whole thing, but since the bug’s been a known issue for at least four years, I can’t rely on it being fixed soon.

I also looked into some techniques that relied on adding a handler to the document or window’s onload event. Unfortunately using attachEvent(), there was no call back to the handler on a refresh, even though script handlers within the page do get called back. It’s possible that setting the onload handler for the window explicitly would have worked, but this can be overwritten by scripts, and so isn’t reliable.

More posts on porting Firefox add-ons to IE

Flashback

Backtothefuture

This ZDNet article really reminded me why I started PeteSearch. It’s from 2004, and laments the lack of progress in searching, and not much has changed since then! Sure, there’s been iterative improvements, more flexible term matching, search history and the like, but nothing that a Google user from 2000 would be surprised by.

Part of the problem is that Google can copy most foreseeable outside innovations if they turn out to be popular. It’s really hard to make a business case for funding a company that would in effect be providing them with free R&D, with little prospect of a return. Google themselves are experimenting with new models, but without real competition, they’re in no rush to cook their golden goose. Ask have been the most innovative with their search UI, but even that is still based around the same basic layout.

One phrase really struck me from the article: "Don’t expect users to apply more than the basic tools and techniques to acquire information from a search engine." The stats show that only three percent of people used quotes or other advanced syntax.

A lot of people have concluded that this means people don’t want anything better, and there’s no point trying to improve the page-of-links presentation of results. My firm belief, and the reason I’m experimenting, is that I think it’s just a local-maximum in the space of possible UIs. Why not have a grid of 25 thumbnails, with the positions of the terms marked on each? Or live snippets of the actual rendered page below each link, not just the text? Or a micro-fiche-style view, where you cycle through all the pages at speed in full-screen? Sure, these are random examples, but are people in 2030 really still going to be using plain pages of links?

Wiki guide to writing BHOs

Hawaii

I’ve had a really good response to my series of articles covering the basics of writing an add-on for Internet Explorer. It led to some really interesting discussions with other people who are working in the same area and finding it hard to discover good documentation. It feels like we’ve all got different pieces of the puzzle, so to help gather that knowledge together, I’ve set up a wiki:

http://petesearch.com/wiki/

I’ve started it off with articles on the basics of creating a BHO, and some of the quirks and issues I’ve run into. It’s publicly editable, so I’m hoping that you folks will help add to, correct and improve it!

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…