When you start distributing your modules to other people you definitely want to version them. Mostly to keep your customers/clients/co-workers from going nuts when it's update time, and avoid the avalanche of support cases you will get if you don’t use versioned updates…
This is done by making sure the extension installation manifest contains the necessary info about what DotNetNuke should do when installing the package on sites where various versions of the module is already installed.
You can work half way to installation magic by knowing how to fiddle around with the manifest, and make quite complex installations. That is outside the scope of this post, though. I will talk about version 5 of the extension installation manifest from a module installation point of view. It will be kind of a basic case of module versioning, but hopefully it will get you started.
I have not found a really good reference on the version 5 extension installation manifest freely avaliable online, but Charles Nurse has written some pieces on the subject, well worth checking out:
The New Extension Installer Manifest – Part 1, Introduction
The New Extension Installer Manifest – Part 2, Component Installers
The New Extension Installer Manifest – Part 3, The Cleanup Component
The New Extension Installer Manifest – Part 4, The Assembly Component
The New Extension Installer Manifest – Part 5, The File Component
The New Extension Installer Manifest – Part 6, The Script Component
It has been in my mind a long time to put together some kind of more or less complete manifest reference, but have not gotten around to it yet.
I don’t in any way claim to be an expert on the subject, but I have found a practice that usually gets me around. Your feedback is most welcome.
Let’s get started.
As a starting point I'll use the manifest we got from my module development tutorial series. You can get the manifest here.
In this update scenario, imagine that we need to make a change in one of the stored procedures and that we want to add an image which will be used in the view control.
Add the file 01.00.01.SqlDataProvider to your module project. This file should contain the database scripts needed to change whatever needs to be changed from version 01.00.00. In our case it would be a script first removing the stored procedure, and then creating the new version of it.
When making changes to tables, it is very important not to drop the table and recreate it. If you do, you will very soon have your customers on the phone wondering why all their precious data went bye-bye when they installed the new version of the module.
Instead, alter the table. This often takes more work to accomplish, but it is the only option you have, really. Hopefully you think I'm silly even mentioning this kind of obvious thing, but I've seen it happen, so just in case...
Open up the manifest file and look at row 2:
<package name="Products" type="Module" version="1.0.0">
Change the version to "1.0.1".
In the scripts element, add a script element for the 01.00.01.SqlDataProvider file. The scripts section should then look like:
When the extension is installed, the system will go through the scripts
section looking for Install scripts. It will execute the scripts in version order, beginning with the first one having a version higher than what is installed. Scripts with a version lower or equal to the one already installed will not run.
Note that the script file names does not have to be the version numbers. I use it because I find it easier to see which version each script belong to.
When uninstalling the module, the script specified in the script tag with type set to UnInstall is executed.
If you create a manifest with DotNetNuke as described here, a version is specified for the UnInstall script. However, as far as I know, that version tag has no function. It works whether or not the version tag is there, or whatever version is set.
In the files element, there should be a file element for each file to be copied into the module folder.
The simplest case is when the file is in the root of the package zip file. Then you use something like:
If the file resides in a subfolder you use the path element inside the file element. The subfolder will be created if it does not exist. So, if the name of the subfolder is images, you use:
If the source file is not located in the same place as the target file, or if it has another name, you use the sourceFileName tag. For example, if the image file is located in the subfolder sourceImages in the installation package and has the name MySourceImage.png:
Usually it doesn't get more complicated than this. Happy versioning!