Learn More





DNN Community Blog

The Community Blog is a personal opinion of community members and by no means the official standpoint of DNN Corp or DNN Platform. This is a place to express personal thoughts about DNNPlatform, the community and its ecosystem. Do you have useful information that you would like to share with the DNN Community in a featured article or blog? If so, please contact .

The use of the Community Blog is covered by our Community Blog Guidelines - please read before commenting or posting.

Everthing you always wanted to know about the DotNetNuke package installer

sdc1Early this week I was at the great OpenForce Europe conference organized by the SDN at The Netherlands.
As always it's been a great conference with lots of great sessions and plenty of opportunities to meet some old DNN friend and made some new ones! Networking (and drinking beers) is as important as good sessions, and we have had both of them!

At my session "DotNetNuke installation manifest file (.dnn) explained!" we took a deep look at all the options provided by DotNetNuke for a installing all kind of Extensions (libraries, modules, providers, skins, ...).

Extending the DotNetNuke Installer

During the session I explained the basic structure of the DNN manifest file (.dnn) and all types of currently supported packages, including the most used (modules, skins, providers) and some others less known (DashboardControl, Widget,...).

Each of those package types support several kind of Component Installers. In DNN 5.x the available component types are:
File, ResourceFile, Assembly, Script, CleanUp, Config, Module, SkinObject, AuthenticationSystem, DashboardControl, CoreLanguage, ExtensionLanguage, Skin, Container and Widget.

Most of these don't require any further discussion since the names are more or less self explanatory.
For all the details of each and any of the components take a look a the Wiki page for the package installer.

Custom Components

One of the hidden gems in the DotNetNuke installer is that it is also extensible.  Not only you can install new DNN extensions but extend the installer itself! Isn't that great?

But why would you need such a feature if DNN already provides a long list of extensions? I will explain a quite common use case that can be easily be solved by taking advantage of this feature.

I've developed a lot of Modules that had to access external databases other than the database where DNN is installed. In many of those scenarios DNN is mainly used as a frontend to access some data repository that is kept apart from the main DNN database for better flexibility (that way the data can always be moved to a different server is performance requires so) and separation of concerns.

It is then very usual that a new version of the module that consumes that data needs to make some changes to the database (new tables, views, storeds, ...). The problem is that by using the default installer it's not possible to install scripts in separate database, instead all scripts will be executed in the main DNN database. So we don't have a way to install a module and make the changes in a single atomic installation.

Enter the ExternalScriptInstaller component!

What we need is a custom script installer that can execute scripts into an external database. The component is defined as:

   1:  <component type="ExternalScript"> 
   2:    <scripts> 
   3:      <basePath>DesktopModules\CustomComponentTestbasePath> 
   4:      <connectionStringName>OtherDBConnectionconnectionStringName> 
   5:      <script type="Install"> 
   6:        <name>00.00.10.sql</name>
   7:        <version>00.00.10</version>
   8:      <script> 
   9:    <scripts> 
  10:  component>

What this will do is execute the script in the SqlServer database pointed by the ConnectionStringName. Obviously this ConnectionString needs to be registered on the web.config.

To support this what we only need is to implement a class that inherits from ComponentInstallerBase. In this case I inherited the class from the ScriptInstaller which in turn inherits from the ComponentInstallerBase.

   1:  Public Class ExternalScriptInstaller 
   2:     Inherits ScriptInstaller

At this point all we need to do is override two methods: ReadManifest() and Install().

   1:  Public Overrides Sub ReadManifest(ByVal manifestNav As XPathNavigator)
   3:      Dim rootNav As XPathNavigator = manifestNav.SelectSingleNode(CollectionNodeName)
   4:      If rootNav IsNot Nothing Then
   5:          'Get the ConnectionStringName
   6:          Dim baseNav As XPathNavigator = rootNav.SelectSingleNode("connectionStringName")
   7:          If baseNav IsNot Nothing Then
   8:              ConnectionStringName = baseNav.Value
   9:          End If
  10:      End If
  12:      MyBase.ReadManifest(manifestNav)
  14:  End Sub

ReadManifest provides and XPathNavigator on the "

Finally the Install() method is called when the installer needs to process the component so at this point we only need to read the connectionstring from the web.config and use that information to execute the SQL scripts provided.

The only missing piece is registering this component installer in DNN so the framework knows about it. Custom installers must be defined in the Lists table using the following values:

  • ListName = "Installer" (fixed) 
  • Value = "ExternalScript" (this is the type of the component as explained above) 
  • Text = DotNetNuke.Services.Installer.Installers.ExternalScriptInstaller (the fully qualified name of the class that implements the installer. In this case it only includes the class name, not the assembly, because I created the class on the App_Code folder).

To install the installer (!) you can create a library installer that copies the class to the App_Code folder and registers it on the Lists table with a sql script.


DotNetNuke provides a very rich set of features for installing new extensions. In most cases these will allow you to install all you need to. But in case you need extra power, the Custom Component Installers open a new path of flexibility for you.

If you need more information take a look at the sections in the Wiki were the manifest file is documented.


Comment Form

Only registered users may post comments.


2sic Daniel Mettler (124)
Aderson Oliveira (15)
Alec Whittington (11)
Alex Shirley (10)
Andrew Nurse (30)
Anthony Glenwright (5)
Antonio Chagoury (28)
Ash Prasad (21)
Ben Schmidt (1)
Benjamin Hermann (25)
Benoit Sarton (9)
Beth Firebaugh (12)
Bill Walker (36)
Bob Kruger (5)
Brian Dukes (2)
Brice Snow (1)
Bruce Chapman (20)
Bryan Andrews (1)
cathal connolly (55)
Charles Nurse (163)
Chris Hammond (203)
Chris Paterra (55)
Clinton Patterson (28)
Cuong Dang (21)
Daniel Bartholomew (2)
Dave Buckner (2)
David Poindexter (3)
David Rodriguez (2)
Doug Howell (11)
Erik van Ballegoij (30)
Ernst Peter Tamminga (74)
Geoff Barlow (6)
Gifford Watkins (3)
Gilles Le Pigocher (3)
Ian Robinson (7)
Israel Martinez (17)
Jan Blomquist (2)
Jan Jonas (3)
Jaspreet Bhatia (1)
Jenni Merrifield (6)
Joe Brinkman (269)
John Mitchell (1)
Jon Henning (14)
Jonathan Sheely (4)
Jordan Coopersmith (1)
Joseph Craig (2)
Kan Ma (1)
Keivan Beigi (3)
Ken Grierson (10)
Kevin Schreiner (6)
Leigh Pointer (31)
Lorraine Young (60)
Malik Khan (1)
Matthias Schlomann (15)
Mauricio Márquez (5)
Michael Doxsey (7)
Michael Tobisch (3)
Michael Washington (202)
Mike Horton (19)
Mitchel Sellers (28)
Nathan Rover (3)
Navin V Nagiah (14)
Néstor Sánchez (31)
Nik Kalyani (14)
Peter Donker (52)
Philip Beadle (135)
Philipp Becker (4)
Richard Dumas (22)
Robert J Collins (5)
Roger Selwyn (8)
Ruben Lopez (1)
Ryan Martinez (1)
Salar Golestanian (4)
Sanjay Mehrotra (9)
Scott McCulloch (1)
Scott S (11)
Scott Wilkinson (3)
Scott Willhite (97)
Sebastian Leupold (80)
Shaun Walker (237)
Shawn Mehaffie (17)
Stefan Cullmann (12)
Stefan Kamphuis (12)
Steve Fabian (31)
Timo Breumelhof (24)
Tony Henrich (3)
Torsten Weggen (2)
Vicenç Masanas (27)
Vincent Nguyen (3)
Vitaly Kozadayev (6)
Will Morgenweck (37)
Will Strohl (163)
William Severance (5)
Try Evoq
For Free
Start Free Trial
a Demo
See Evoq Live
Need More Information?