WiX Script for installing Live Writer Plugins
Here's a WiX install script to build an MSI to install a Windows Live Writer (WLW) plugin dll, by xcopying the plugin dll to the Plugins directory. You can then upload your MSI to the WLW Gallery and share your plugin with others.
WLW Plugins are very easy to write, so it's nice to have them easy to install too.
(An MSI is a Windows Installer Binary that contains both the content to install and the directions for installation. ) You could also use VS Deployment projects is an alternative way to produce MSIs. (That's probably worthy of its own entry, but see "How to: Use a Registry Launch Condition to Specify a Target Directory" for hints).
Disclaimer + Thanks
See the rules for distributing WLW plugins. In this case, I'll xcopy the plugin.dll to %installDir%\PlugIn, where %installDir% is where WLW is installed, as determined by the "InstallDir" registry value at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Live\Writer. (Note this value changed with Beta 3). There are other install options.
I'm not an installer guy. This was a pertinent reason to learn more about installers. WiX documenation is rarer than gold, but there's a nice tutorial and various Wix Ninjas (thanks Daniel Harvey!) kindly helped me worked through some WiX learning curve issues.
I started with Bonnie's wix script here. (This was what I used for my first plugin. Unfortunately, that script was subject to the beta 3 breaking changes). Bonnie and Joe Cheng kindly helped me get it working for my plugin.
This script starts with Bonnie's and has a few updates:
- It's updated for Wix 2.0.5325.0. (thanks Bonnie!)
- It properly looks up %InstallDir% in the registry, (instead of using "%ProgramFiles%\Windows Live Writer").
- It detects pre-Beta 3 installs and gives a specific upgrade message (instead of not finding WLW installs for pre-beta 3)
- Originally, I also added a way to remove the per-plugin options storage (which is under HKCU), but later figured that was a bad idea after reading. So that code is commented out below.
- Added more comments about what was going on. WiX is code and like any code, comments make it more understandable.
Getting down to business.
So here's step-by-step:
1) Download the WiX toolset, if you don't already have it. This is tested against Wix, 2.0.5325.0, which you can download from here.
2) Take this WiX Script and substitute all {%...%} with appropriate values. Descriptions and sample values are given below.
<?xml version="1.0" encoding="utf-8" ?> <Wix xmlns="https://schemas.microsoft.com/wix/2003/01/wi"> <!-- Wix Installer for a WLW PlugIn. Verified against Wix version 2.0.5325.0. This is adapted from https://bplo.spaces.live.com/blog/cns!CF2831C0AE64E81B!210.entry. See https://msdn2.microsoft.com/en-us/library/aa738841.aspx for rules on distributing plug-ins. 1) The RegKey "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Live\Writer\InstallDir" tells what directory WLW is installed in. This is valid in Beta 3. 2) If "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Live\Writer InstallDir" is defined instead, then a pre-Beta 3 version is installed. 3) Copy the Files to the PlugIn sub-directory of that #1. Other caveats: - This does not support Upgrading a PlugIn. - To specify a License, include 'License.rtf' file in the current directory when you run Light.exe. - This uses a minimal UI. --> <Product Name="{%Installed Name%}" Id="{%guid #1%}" Language="1033" Codepage="1252" Version="1.0.0" Manufacturer="{%Manufacturer%}"> <Package Id="????????-????-????-????-????????????" Description="{%Description%}" Manufacturer="{%Manufacturer%}" InstallerVersion="200" Compressed="yes" /> <!-- This script is very basic and doesn't have any custom UI --> <UIRef Id="WixUI_Minimal" /> <!-- Lookup the installation directory from the registry. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Live\Writer\InstallDir This registry key moved with Beta 3, so lookup the old key to detect pre-beta 3 installs and advise an upgrade. INSTALLDIR is where the new (beta 3 and beyond) registry entry is. INSTALLDIR_OLD is where the old (pre-beta 3) registry entry is. --> <Property Id="INSTALLDIR"> <RegistrySearch Id='GetInstallDir' Type='raw' Root='HKLM' Key='SOFTWARE\Microsoft\Windows Live\Writer' Name='InstallDir' /> </Property> <Property Id="INSTALLDIR_OLD"> <RegistrySearch Id='GetOldInstallDir' Type='raw' Root='HKLM' Key='SOFTWARE\Microsoft\Windows Live Writer' Name='InstallDir' /> </Property> <!-- Launch Conditions. Ensure that WLW is actually installed --> <Condition Message="An old version of Windows Live Writer is installed. Please upgrade to the latest version at https://writer.live.com ."> <![CDATA[ NOT (INSTALLDIR_OLD AND (NOT INSTALLDIR)) ]]> </Condition> <Condition Message="Windows Live Writer is not installed. Please install Windows Live Writer from https://writer.live.com ."> <![CDATA[ NOT ((NOT INSTALLDIR) AND (NOT INSTALLDIR_OLD)) ]]> </Condition> <!-- End of Launch conditions --> <Media Id="1" Cabinet="{%PluginName%}.cab" EmbedCab="yes" DiskPrompt="CD-ROM #1" /> <Property Id="DiskPrompt" Value="{%PluginName%} Installation [1]" /> <Directory Id="TARGETDIR" Name="SourceDir"> <Directory Id="INSTALLDIR"> <Directory Id="Plugins" Name="Plugins"> <Component Id="{%PluginName%}" Guid="{%guid #3%}"> <!-- The raw dll to copy to the PlugIns folder --> <File Id="File_{%PluginName%}" Name="{%PluginShortFilename%}" LongName="{%PluginLongFilename%}" DiskId="1" Source="{%FullPath%}" Vital="yes" /> <!-- The IProperties backing storage to delete. This key is populated if the PlugIn stores options via IProperties. Remove it on uninstall to ensure that the plugin options get reset.
<!-- Uncomment this to remove IProperties storage on uninstall. This just removes the current user. <Registry Id='FoobarRegInstallDir' Root='HKCU' Key='Software\Microsoft\Windows Live\Writer\Preferences\PostEditor\ContentSources\{%PlugIn Guid%}' Action='removeKeyOnUninstall' /> -->
<!-- {note: other files could be included here an necessary; if you distribute help files or supporting graphics} --> </Component> </Directory> </Directory> </Directory> <!-- Components are grouped into "Features". As a plug-in, we have a single feature, which is to copy the plugin dll. We don't have any UI to select features. --> <Feature Id="Complete" Level="1" Title="{%PluginName%}" Description="{%Description%}" Display="expand"> <ComponentRef Id="{%PluginName%}" /> </Feature> </Product> </Wix>
The values I used for my Verse-of-the-Day plugin were:
Key | Description | Sample Value |
Guid #1 | A unique guid for the product. | {YOURGUID-ca12-470b-ade3-3cfca0c7d4c3} |
Guid #3 | A unique guid for the component. | {YOURGUID-ca12-470b-ade3-3cfca0c7d4c3} |
Installed Name | The name that shows in Control Panel's Add/Remove programs list. | Verse-of-the-Day Live Writer PlugIn |
Manufacturer | Your name. | Mike Stall |
Description | A description of your plugin, which may be presented to the end-user. | Insert a verse of the Day from BibleGateway |
PluginName | The name of your plugin. This is used internally for WiX property names and not displayed to the end user. | VerseOfTheDay |
PluginShortFilename | a 8.3 dll name for your plugin. | VOTD.dll |
PluginLongFilename | A long dll name for your plugin. | VerseOfTheDay.dll |
FullPath | The path to the dll on your target machine. WiX will copy this into the MSI. | C:\temp\msi\3\votd\VerseOfTheDay.dll |
PlugIn Guid | The Guid in the Plugin attribute. | {6F75058E-EED6-4f8c-BBE5-BE0D6126358D} |
Random guids (Guid #1, etc) can be generated from GuidGen (in VS, "Tools | Create GUID"), or C# code like: Guid.NewGuid().ToString("b").
(FWIW, substituting the {%...%} was what motivated my Replacer tool)
3) Compile with WiX.
First, set WIXUI_PATH to the wix installation (where candle.exe lives). And then run these Wix commands:
|
This takes in the wix file (votd.wxs) and produces an output file, MyVOTD.msi, which you can then submit to the WLW Gallery.