I use DotNetNuke extensively for building Enterprise applications for my clients (you might be interested in checking out iClinic, or iMLM etc.). DNN together with ASP.NET & Sql Server put forward extreme power and flexibility in your hands as a Solution Architect, together with great off-the-shelf features, a perfect platform to build upon.

As can be imagined, these custom solutions are further built-up as a collection of DNN modules. And as a DNN module developer, you are already aware that you use module installation packages (.zip files) that consist of a module definition file (.dnn) to guide the installation of your DNN module. Now, I recently had a situation where I needed a couple of modules from one of these solutions to share some common images. And I thought it would be best to place these images in the native DNN images folder (which is in the root of your DNN installation). Further, I wanted to replace some default images from the folder itself.

The problem was that the DotNetNuke Private Assembly Installer (PAInstaller – the component of DNN handling package installations) recognizes only DLL files as special ones as far as the placement of package files upon installation is concerned. These files are automatically put to the installation’s bin folder.

Another lesser known feature is token replacement for App_Code folder. You can use the following in the files section of your module definition file:

 

<file>
	<path>[app_code]</path>
	<name>Class1.vb</name>
</file>

In response to this, the source file Class1.vb would be placed in the App_Code folder on the installation (be advised that DNN would place it in a sub-folder of App_Code named after your module name, and would also create an entry for it in web.config’s <codeSubDirectories> section – sensible you would agree). However, if you used this:

 

<file>
	<path>[app_code]dir</path>
	<name>Class1.vb</name>
</file>

Class1.vb would now go to App_Code\ModuleName\dir folder (Again notice, there is no slash before dir above, you need not specify it).

However, this did not resolve my problem. I wanted to place my files in the images folder, which is not supported by the PAInstaller (using <path>[images]</path> actually created a sub-folder named [images] in DesktopModules\ModuleName, and placed the file there – funny).

One easy option here could have been to implement IUpgradable interface in the BusinessControllerClass for the module, and move the files to appropriate folders there manually. However, I strongly felt there should be some way to accomplish this from the module definition file itself. And after some fiddling around with the file and the Installer, I finally found my way out.

In the end, it was as simple as using the good old double-dot(..) placeholders for a parent directory. Let’s take an example:

 

<file>
	<path>..\..\images</path>
	<name>accept.png</name>
</file>

The above entry in the files section would put the file “accept.png” from your module installation package to the “images” folder inside the root of your DNN installation. Here the first set of double-dots took us one level up from our module folder to the DesktopModules folder, and the second to the root of the installation, from where we entered the images folder.

Remember, the file accept.png should itself reside in the root of your installation package (not inside a sub-folder and certainly not inside the Resource file for the module, if any).

I have tested this approach on both DNN 4.x & DNN 5.x, and it works perfectly on both.

Moving forward, I would expect the PAInstaller itself to be enhanced to support tokens (like [app_code]) for all native DNN folders.

A sample DNN installation package attached below demonstrates copying files both to the [app_code] as well as images folder, which can easily be extended for copying files to any other folder during installation.