The one catch is that to put PlugIns on the WLW Gallery you need to upload an Windows Installer (MSI) file. Putting plugins on the gallery has a few advantages over just throwing it a random URL, including:
– the gallery makes it much easier to share them with others.
– the gallery is searchable, and can help find related plugins
– the gallery supports various community features like star ratings and reviews.
But perhaps most usefully, the WLW Client has a “Add a Plugin” feature that jumps straight to the gallery. So putting your plugin on the gallery makes it much more available to users.
So there’s good incentive to figure out how to get an MSI file around your plugin dll.
I previously posted a Wix snippet to xcopy the dll, but I wanted to talk about the more general problem space here.
The most important background is that I’m not really a setup guy, and I don’t have membership in the elite group of Elite Setup Ninjas. But after getting burned by making mistakes here, and getting some valuable tips from kindly ESNs, I think I’m getting the hang of this. I’m writing this not because I know so much about setup or WLW, but because writing WLW is fun and this is a key part of that.
So a WLW PlugIn can be just a simple dll that links against WindowsLive.Writer.Api.dll and implements a minimal contract. (See example)
The MSDN page on distributing plugins describes 2 basic ways to let WLW know about your PlugIn:
- Copy the PlugIn dll to the the PlugIns subdirectory under the WLW installation. The WLW install folder can be found via the HKLM\SOFTWARE\Microsoft\Windows Live\Writer\InstallDir registry value.
- Add a registry key under [HKCU|HKLM]\SOFTWARE\Windows Live\Writer\PluginAssemblies.
Each of these has its own advantages.
#1 is pure xcopy deployment and so appears simplest. But it’s xcopy to %InstallDir%\PlugIns, so it’s xcopy based off a registry lookup, which has some extra complexity. The pure-xcopy here can be nice, especially for informal, non-MSI installs.
#2 includes setting registry values, but the registry and file paths are constant and independent of WLW’s path or installation status. That has the advantage that it decouples the Plugin from WLW. So you can install the PlugIn wherever you want. This has the nice property that you can just install and uninstall all components in any order, and everything keeps working.
#1 is an easier post build step for local projects, but actually a more complex installer than #2 since it’s not constant paths.
However, #1 has a dependency that creates a higher degree of coupling between the PlugIn and WLW. For example, the PlugIn installer needs to check for %InstallDir%, or that WLW is uninstalled before the PlugIn is uninstalled.
Design note: Extra complexity means extra mistakes
The extra complexity of technique #1 often (based off my informal searching for a solution) causes installers to do it wrong. I notice a few wrong ways:
Bad technique #1: Ignore %installdir%:
Many PlugIn installers I see tend to ignore %InstallDir% and just xcopy to a hard-coded path like %ProgramFiles%\Windows Live Writer\PlugIns. That’s easy because it skips the registry lookup, but technically wrong for the WLW protocol; it’s not robust in the case that the %InstallDir% moves around, (such as with WLW beta 3)
Bad technique #2: using file associations:
I notice some other techniques use heuristics like use file associations. For example, WLW creates “.wpost” files, so some installers use AssocQueryString to find the application associated with that file extension, and then assume that application is WLW writer. Again, this is bad because it’s fragile:
– what if the association gets broken?
– what if another app registers that association?
– what if a future version of WLW uses a different association (.wpostx?)
Also, it’s not on the official correct list of how to distribute plugins.
Custom Data and IProperties:
Furthermore, PlugIns can have options which get persisted across WLW instances (see WindowsLive.Writer.API.Properties). Empirically, this data is stored in a HKCU registry key (you can search the registry and find it). The guys on the WiX mail list and Raymond Chen recommend just leaving that per-user data on uninstall, and their arguments convince me. Particularly, it’s not practical or smart to try and uninstall the HKCU data for all possible users.
So that’s 1 less thing for the installer to worry about. The downside is that if your plugin has complex settings and you screw them up, uninstall + reinstall won’t restore them. But there’s a few mitigating factors there. (How complex of settings will a plugin have? Will they ever get to a state where you can’t fix them? And worst case, you complain on some fourm and somebody tells you how to nuke the registry key)
There two deployment options: (xcopy to PlugIns or registry keys).
There are two common solutions for writing the installers, both of which are powerful enough to handle either deployment option:
- Write a Wix script.
- Use VS Deployment projects.
So a full example matrix here would be 2×2=4. I previously posted how to use Wix to do the xcopy, which I think is the most complex installer technique in the matrix. See MSDN for VS Deployment Projects. Key sections there are installing to a registry location, and writing registry keys.