Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

DotNetNuke Module Packaging for the Terminally Broke

0.00/5 (No votes)
14 May 2009 1  
How to create a module package without giving away your source code.

Introduction

So, you've been dabbling with DNN modules for a while, and now you've written something you'd like to sell. But you don't fancy giving away your source code - what to do, what to do?

If you've been looking around a bit, you've probably come across Michael Washington's article on how to package your DNN module as a compiled assembly. Great article, one drawback: this won't work if you are one broke developer, using Visual Web Developer Express (because it's free, hooray!).

If you've been crying silently into your coffee over this issue, despair no longer, there's a solution (thanks to jamesche's excellent article on using the aspnet_compiler in VWD Express).

These here musings on the subject pull those two articles together and fill in the missing bits...

Step 1: Creating the External Tool

This is pretty much the same as outlined in jamesche's article. Launch your DNN site in VWD and select Tools->External Tools. You'll get the external tools creation window. Now:

  1. Enter 'Pre-Compile (DNN)' as the title.
  2. Click on the ellipsis next to the 'Command' text box, navigate to c:\Windows\Microsoft.NET\Framework\v2.0.50727 and select aspnet_compiler.exe.
  3. In the Arguments text box, enter the following string: -p "$(ProjectDir)" -v / "$(ProjectDir)\..\CompiledDNNSite" -u -fixednames.
  4. If you've copied and pasted the above argument string, double-check that the double quotes have not been converted to smart quotes. In fact, it's best to do the string by hand anyway. The $(ProjectDir) can be inserted correctly by clicking on the arrow to the right of the text box and selecting "Project Directory" from the pop-up menu.
  5. If you want the Command Prompt to close automatically after doing the pre-compile, check the "Close on Exit" checkbox.

If you've looked at jamesche's original instructions for setting up the compiler, you'll have noticed (because you've been paying attention) that I've added two more options, -u and -fixednames. Just a quick explaination: -u makes sure that your .ascx files are not included in the compiled package. They're just updated to reference the compiled version of the code-behind files. All the DNN modules that I've seen so far leave the .ascx files so that the customer can edit them to tweak the module's appearance - fair enoughski. The -fixenames option makes sure that each page gets its own assembly. Leave that one out, and you won't know which DLLs are yours and which ones aren't. Go on, give the whole thing a try with -u and -fixednames left out, I dare you. You'll see...

You should now have an external tool called (not surprisingly) "Pre-Compile (DNN)". Run it, and your compiled DNN site will appear in a directory called CompiledDNNSite, which should have the same root as your non-compiled DNN site. I'm sure you'll find it. If you look in the /bin folder, you'll see all the lovely DLLs that you've wanted for so long...

Step 2: Creating a Source Code Module Package

Well, you may as well make use of the automatic module packaging bits of DNN. Go to Host->Module Definitions, and click on the cute little pencil left of the module you want to flog. You'll see all the module package info. (I assume that you're aware of the little feature of the module starter kit that puts slightly wrong module and folder names in the first two boxes. Just replace them with the correct values, it's pretty obvious.) At the bottom of the page. there's a link, helpfully labeled "Create Module Package". Click it, stick with the default name for the zip file (unless you don't like it, in which case, by all means, go wild...). Tick the "Create Manifest File?" checkbox. and click "Create". You should find the module in the "Install\Module" folder of your DNN site.

You now have a source code module package. If I were you, I'd test it to make sure it installs OK. Otherwise, the process of finding the error after you've created the compiled module package will be long and painful, like a python with several slipped discs.

Step 3: Replacing Source Code Files with Compiled Assemblies

Once you're sure that the module package works OK, unzip it (to a folder outside of your DNN site; otherwise, if you have to re-compile for some reason, you'll get duplicate DLLs!).

Make a note of all files related to code (.cs, .vb, .config, and .ascx) (and .xsd and .xss if you're using DataSets!).

The ASP.NET compiler has created a load of compiled assemblies, unfortunately without any hint as to the original structure of the DNN site. Everything's lopped together in the /bin folder. So, you need to puzzle things out. First, the easy bit, the .ascx files. Because we excluded them from the compiled assemblies, they have not been placed in the /bin directory, but in the relevant DesktopModules folder. So, if your module's source code was in a folder called "MyWonderfulModule", you should now have the .ascx files you need in CompiledDNNSite\DesktopModules\MyWonderfulModule. Remove the original .ascx files from your unzipped archive and replace them with the ones from your compiled site.

Next, you need to find all the DLLs corresponding to your module's code-behind files. They will have filenames like App_Web_viewprofile.ascx.390b2b.dll. All compiled code from the DesktopModules directory will start with App_Web, which is helpful, but...

Take a look at the longishy list of DLLs, all starting with App_Web_Settings. One for each module that has a Settings.ascx file, be they yours or someone else's. Fortunately, there's a little trick you can leverage. Hopefully, your module will have at least one .ascx file with a completely unique name, say, ViewMyWonderfulModule.ascx. You should have one (and only one) corresponding DLL in your CompiledDNNSite\bin directory, something along the lines of App_Web_ViewMyWonderfulModule.ascx.123xyz.dll.

Here's the trick: all files compiled from your DesktopModules/MyWonderfulModule folder will have the same code number. So copy that, and let the annoying paper clip do something useful for a change - search for filenames containing that string.

Search for filenames containing the code

This should give you a list of all the DLLs you need. (OK, the module I'm using as an example here has no settings control, but you get the idea...)

Results

Just select all files and move them over to your unzipped module package. There should be one for each code-behind file (.cs or .vb). Double-check, then delete the original source code files.

OK, now for the DAL code. That's quite easy, actually. All DAL code, including DataSets, should have been compiled into a single DLL, starting with App_SubCode, e.g., App_SubCode_MyWonderfulModule.dll. Add this file to your folder and you should have all your compiled code where you need it.

Lastly, you need to delete any .config files that may have snuck in. Now, you should have all the files you need, but you still have to tell DNN about them.

Step 4: Updating the Manifest File

Open the .dnn file inside your module installation package and scroll down to the list of files that make up the module. This list still references the .cs, .vb, and .config files you've deleted, so it's got to be updated...

The manifest file lists all the files that make up the completed module inside <file>...</file> tags. Simply remove all the references to files you've deleted, and add references to the files you've added. Simple as that.

Before:

<files>
    <file>
      <path>App_LocalResources</path>
      <name>EditTaskList.ascx.resx</name>
    </file>
    <file>
      <path>App_LocalResources</path>
      <name>Settings.ascx.resx</name>
    </file>
    <file>
      <path>App_LocalResources</path>
      <name>ViewTaskList.ascx.resx</name>
    </file>
    <file>
      <name>01.00.00.SqlDataProvider</name>
    </file>
    <file>
      <name>EditTaskList.ascx</name>
    </file>
    <file>
      <name>EditTaskList.ascx.cs</name>
    </file>
    <file>
      <name>module.css</name>
    </file>
    <file>
      <name>Uninstall.SqlDataProvider</name>
    </file>
    <file>
      <name>ViewTaskList.ascx</name>
    </file>
    <file>
      <name>ViewTaskList.ascx.cs</name>
    </file>
    <file>
      <path>[app_code]</path>
      <name>DataProvider.cs</name>
    </file>
    <file>
      <path>[app_code]</path>
      <name>SqlDataProvider.cs</name>
    </file>
    <file>
      <path>[app_code]</path>
      <name>TaskDataSet.xsd</name>
    </file>
    <file>
      <path>[app_code]</path>
      <name>TaskDataSet.xss</name>
    </file>
    <file>
      <path>[app_code]</path>
      <name>TaskListController.cs</name>
    </file>
</files>

After:

<files>
    <file>
      <path>App_LocalResources</path>
      <name>EditTaskList.ascx.resx</name>
    </file>
    <file>
      <path>App_LocalResources</path>
      <name>Settings.ascx.resx</name>
    </file>
    <file>
      <path>App_LocalResources</path>
      <name>ViewTaskList.ascx.resx</name>
    </file>
    <file>
      <name>01.00.00.SqlDataProvider</name>
    </file>
    <file>
      <name>EditTaskList.ascx</name>
    </file>
    <file>
      <name>App_Web_edittasklist.ascx.ee0a509f.dll</name>
    </file>
    <file>
      <name>module.css</name>
    </file>
    <file>
      <name>Uninstall.SqlDataProvider</name>
    </file>
    <file>
      <name>ViewTaskList.ascx</name>
    </file>
    <file>
      <name>App_Web_viewtasklist.ascx.ee0a509f.dll</name>
    </file>
    <file>
      <name>App_SubCode_TaskList.dll</name>
    </file>
</files>

And, that's it! You're done! Go and flog your module!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here