Friday, April 19, 2019
 Now reading ...
Dec
5
Sat
Posted By Subodh on Saturday, December 05, 2009
3925 Views


Packaging multiple DNN Modules in DotnetNuke 5.0+

How does somebody package a DNN module? Login as host, go to Module Definitions, hit Edit on the module you want to package and voila, there’s a Create Package button!

 

How do you create a package from command line? Or, how do you create a package that contains multiple packages? I have to admit, I couldn’t Google enough to find a solution. having spent a fair part of my Saturday looking for a solution, I just ended up experimenting. And writing my own solution.

The Oracles of DNN, the keepers of all knowledge, please tell me if I recreated something already available out there? No, I’m not talking about NANT. All I wanted was an easy way to package a few modules as one! For DNN 5.0 (since you changed the Package Installer). There are a lot of sites out there that claim that having multiple package nodes inside of <packages> node would create a package that can install multiple modules. I tried editing the .dnn file. But the installer just won’t create a package. So, here it goes; a down and dirty 30 minute C# code that can create a package straight via command line. And now I don’t need NANT, I don’t need the UI way of packaging. Just  simple port build command line would do.

 

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5: using System.Diagnostics;
   6: using System.IO;
   7: using System.Xml;
   8: using ICSharpCode.SharpZipLib.Zip;
   9: namespace Subodh.Modules.DNNPackager
  10: {
  11:     class Program
  12:     {
  13:         static void Main(string[] args)
  14:         {
  15:             if (args.Length < 3) PrintUsage();
  16:             if (args.Length >= 3)
  17:             {
  18:                 string sSourceDirectory = args[0];
  19:                 string sManifestFileName = args[1];
  20:                 string sManifestFilePathFull = sSourceDirectory + "\\" + sManifestFileName;
  21:                 string sTargetPath= args[2];
  22:                 string sPackageName = "";
  23:                 XmlDocument xManifest = new XmlDocument();
  24:                 xManifest.Load(sManifestFilePathFull);
  25:                 string sManifestRootNode = xManifest.DocumentElement.Name;
  26:                 if (sManifestRootNode == "dotnetnuke")
  27:                 {
  28:                     XmlNodeList xPackages= xManifest.SelectNodes("//packages/package[@type='Module']");
  29:                     if (xPackages.Count > 0)
  30:                     {
  31:                         XmlElement xFirstPackageNode = (XmlElement)xPackages[0];
  32:                         string sPkg1Name = xFirstPackageNode.GetAttribute ("name");
  33:                         string sPkg1Version= xFirstPackageNode.GetAttribute ("version");
  34:                         if (sPkg1Name != "" && sPkg1Version != "")
  35:                         {
  36:                             sPackageName = sPkg1Name + "_" + sPkg1Version;
  37:                         }
  38:                         else ExitWith(2, "Cant find name and version");
  39:                         string sWorkingDirectory = System.IO.Directory.GetCurrentDirectory() +"\\Temp";
  40:                         if (Directory.Exists(sWorkingDirectory)) Directory.Delete(sWorkingDirectory, true);
  41:                         DirectoryInfo di = Directory.CreateDirectory(sWorkingDirectory);
  42:                         foreach (XmlElement xPackage in xPackages)
  43:                         {
  44:                             CopyFiles(sSourceDirectory, di.FullName, xPackage);
  45:                         }
  46:                         CopyFile(sSourceDirectory, di.FullName, sManifestFileName);
  47:                         BuildCompressedPackage(di.FullName, System.IO.Directory.GetCurrentDirectory(), sPackageName + ".zip");
  48:                         
  49:                     }
  50:                     else ExitWith(1, "Unable to find any module package declarations");
  51:  
  52:                 }
  53:                 else ExitWith(1, "Not a DNN package type");
  54:             }
  55:             ;
  56:  
  57:         }
  58:  
  59:         private static void CopyFiles(string sSourceDir, string sTargetDir, XmlNode xPackage)
  60:         {
  61:             XmlElement xLicense = (XmlElement)xPackage.SelectSingleNode("license");
  62:             XmlElement xReleaseNotes = (XmlElement)xPackage.SelectSingleNode("releaseNotes");
  63:             if (xLicense != null)
  64:             {
  65:                 if (xLicense.HasAttribute("src")) CopyFile(sSourceDir, sTargetDir, xLicense.GetAttribute("src"));
  66:             }
  67:             if (xReleaseNotes != null)
  68:             {
  69:                 if (xReleaseNotes.HasAttribute("src")) CopyFile(sSourceDir, sTargetDir, xReleaseNotes.GetAttribute("src"));
  70:             }
  71:  
  72:             XmlNode xScriptComponent = xPackage.SelectSingleNode("components/component[@type='Script']");
  73:             XmlNode xModuleComponent = xPackage.SelectSingleNode("components/component[@type='Module']");
  74:             XmlNode xAssemblyComponent = xPackage.SelectSingleNode("components/component[@type='Assembly']");
  75:             XmlNode xFileComponent = xPackage.SelectSingleNode("components/component[@type='File']");
  76:             if (xScriptComponent!=null) CopyFilesFromScriptComponents(sSourceDir, sTargetDir, xScriptComponent);
  77:             if (xModuleComponent!=null) CopyFilesFromModuleComponents(sSourceDir, sTargetDir, xModuleComponent);
  78:             if (xAssemblyComponent!=null) CopyFilesFromAssemblyComponents(sSourceDir, sTargetDir, xAssemblyComponent);
  79:             if (xFileComponent!=null) CopyFilesFromFileComponents(sSourceDir, sTargetDir, xFileComponent);
  80:  
  81:         }
  82:         private static void CopyFilesFromFileComponents(string sSourceDir, string sTargetDir, XmlNode xFileComponent)
  83:         {
  84:             string sbasePath = "";
  85:             XmlElement xBasePath = (XmlElement)xFileComponent.SelectSingleNode("files/basePath");
  86:             if (xBasePath != null) sbasePath = xBasePath.InnerText.Trim();
  87:             if (sSourceDir.EndsWith(sbasePath)) sbasePath = "";
  88:             XmlNodeList xFiles = xFileComponent.SelectNodes("files/file");
  89:             foreach (XmlNode xFile in xFiles)
  90:             {
  91:                 XmlNode xPath = xFile.SelectSingleNode("path");
  92:                 XmlNode xName = xFile.SelectSingleNode("name");
  93:                 string sFileName = xName.InnerText.Trim();
  94:                 string sSourceDir2 = sSourceDir + "\\" + sbasePath + "\\";
  95:                 string sTargetDir2 = sTargetDir + "\\" + sbasePath + "\\";
  96:                 if (xPath != null && xPath.InnerText != "")
  97:                 {
  98:                     sSourceDir2 += xPath.InnerText.Trim();
  99:                     sTargetDir2 += xPath.InnerText.Trim();
 100:                 }
 101:                 CopyFile(sSourceDir2, sTargetDir2, sFileName);
 102:             }
 103:         }
 104:         private static void CopyFilesFromAssemblyComponents(string sSourceDir, string sTargetDir, XmlNode xAssemblyComponent)
 105:         {
 106:             string sbasePath = "";
 107:             XmlElement xBasePath = (XmlElement)xAssemblyComponent.SelectSingleNode("assemblies/basePath");
 108:             if (xBasePath != null) sbasePath = xBasePath.InnerText.Trim();
 109:             if (sSourceDir.EndsWith(sbasePath)) sbasePath = "";
 110:             XmlNodeList xAssemblies = xAssemblyComponent.SelectNodes("assemblies/assembly");
 111:             foreach (XmlNode xAssembly in xAssemblies)
 112:             {
 113:                 XmlNode xName = xAssembly.SelectSingleNode("name");
 114:                 string sFileName = xName.InnerText.Trim();
 115:                 string sReplPath = "";
 116:                 if (sSourceDir.ToLower().IndexOf("\\desktopmodules") > 0)
 117:                 {
 118:                     sReplPath = sSourceDir.Substring(sSourceDir.ToLower().IndexOf("\\desktopmodules"));
 119:                 }
 120:                 string sSourceDir2 = sSourceDir.Replace (sReplPath,"") + "\\"+sbasePath;
 121:                 string sTargetDir2 = sTargetDir + "\\" + sbasePath + "\\";
 122:                 CopyFile(sSourceDir2, sTargetDir2, sFileName);
 123:             }
 124:         }
 125:         private static void CopyFilesFromScriptComponents(string sSourceDir, string sTargetDir, XmlNode xScriptComponent)
 126:         {
 127:             string sbasePath = "";
 128:             XmlElement xBasePath = (XmlElement )xScriptComponent.SelectSingleNode("scripts/basePath");
 129:             if (xBasePath != null) sbasePath = xBasePath.InnerText.Trim();
 130:             if (sSourceDir.EndsWith(sbasePath)) sbasePath = "";
 131:             XmlNodeList xInstallScripts = xScriptComponent.SelectNodes("scripts/script[@type='Install' or @type='UnInstall']");
 132:             foreach (XmlNode xScript in xInstallScripts)
 133:             {
 134:                 XmlNode xPath = xScript.SelectSingleNode("path");
 135:                 XmlNode xName = xScript.SelectSingleNode("name");
 136:                 string sFileName = xName.InnerText.Trim();
 137:                 string sSourceDir2 = sSourceDir + "\\" + sbasePath + "\\";
 138:                 string sTargetDir2 = sTargetDir  + "\\" + sbasePath + "\\";
 139:                 if (xPath != null && xPath.InnerText != "")
 140:                 {
 141:                     sSourceDir2 += xPath.InnerText.Trim();
 142:                     sTargetDir2 += xPath.InnerText.Trim();
 143:                 }
 144:                 CopyFile(sSourceDir2, sTargetDir2, sFileName);
 145:             }
 146:         }
 147:         private static void CopyFilesFromModuleComponents(string sSourceDir, string sTargetDir, XmlNode xModuleComponent)
 148:         {
 149:             XmlNodeList xControlSrcs = xModuleComponent.SelectNodes("desktopModule/moduleDefinitions/moduleDefinition/moduleControls/moduleControl/controlSrc");
 150:             foreach (XmlNode xControlSrc in xControlSrcs)
 151:             {
 152:                 string sControlPath = ((XmlElement) xControlSrc).InnerText.Trim();
 153:                 string sReplPath="";
 154:                 if (sSourceDir.ToLower().IndexOf("\\desktopmodules") > 0)
 155:                 {
 156:                     sReplPath = sSourceDir.Substring(sSourceDir.ToLower().IndexOf("\\desktopmodules"));
 157:                 }
 158:                 sControlPath = sControlPath.Replace("/", "\\");
 159:                 //string sTargetDir2 = sTargetDir + sReplPath;
 160:                 if (sReplPath.StartsWith("\\")) sReplPath = sReplPath.Substring(1);
 161:                 sControlPath = sControlPath.Replace(sReplPath+"\\", "");
 162:                 CopyFile(sSourceDir, sTargetDir, sControlPath);
 163:             }
 164:         }
 165:         private static void CopyFile(string sSourceDir, string sTargetDir, string sFileName)
 166:         {
 167:             try
 168:             {
 169:                 string sSourcePath = sSourceDir + "\\" + sFileName;
 170:                 string sTargetPath = sTargetDir + "\\" + sFileName;
 171:                 sSourcePath = sSourcePath.Replace("\\\\", "\\");
 172:                 sTargetPath = sTargetPath.Replace("\\\\", "\\");
 173:                 sSourcePath = sSourcePath.Replace("\\\\", "\\");
 174:                 sTargetPath = sTargetPath.Replace("\\\\", "\\");
 175:                 if (!Directory.Exists(sTargetPath.Replace("\\" + sFileName,""))) Directory.CreateDirectory(sTargetPath.Replace("\\" + sFileName,""));
 176:                 File.Copy(sSourcePath, sTargetPath,true);
 177:             }
 178:             catch (Exception exp)
 179:             {
 180:                 ExitWith(5, "Could not find File " + exp.Message);
 181:             }
 182:         }
 183:  
 184:  
 185:         private static void BuildCompressedPackage(string SourceDirectory, string PackagePath, string PackageName)
 186:         {
 187:             try
 188:             {
 189:                 
 190:                 using (ZipOutputStream s = new ZipOutputStream(File.Create(PackagePath + "\\" + PackageName + ".zip")))
 191:                 {
 192:                     s.SetLevel(9); // 0-9, 9 being the highest compression
 193:                     CompressDir(SourceDirectory, SourceDirectory, s);
 194:                     s.Finish();
 195:                     s.Close();
 196:                 }
 197:             }
 198:             catch (Exception exp)
 199:             {
 200:                 Console.WriteLine(exp);
 201:             }
 202:         }
 203:  
 204:         private static void CompressDir(string ParentPath, string SourceDirectory, ZipOutputStream s)
 205:         {
 206:             string[] filenames = Directory.GetFiles(SourceDirectory);
 207:             byte[] buffer = new byte[4096];
 208:             foreach (string file in filenames)
 209:             {
 210:                 string sFilePath = SourceDirectory.Replace(ParentPath, "");
 211:                 if (sFilePath.Trim() != "")
 212:                 {
 213:                     if (sFilePath.StartsWith("\\")) sFilePath = sFilePath.Substring(1);
 214:                     if (!sFilePath.EndsWith("\\")) sFilePath += "\\";
 215:                 }
 216:                 ZipEntry entry = new ZipEntry(sFilePath + Path.GetFileName(file));
 217:                 entry.DateTime = DateTime.Now;
 218:                 s.PutNextEntry(entry);
 219:                 using (FileStream fs = File.OpenRead(file))
 220:                 {
 221:                     int sourceBytes;
 222:                     do
 223:                     {
 224:                         sourceBytes = fs.Read(buffer, 0, buffer.Length);
 225:                         s.Write(buffer, 0, sourceBytes);
 226:                     }
 227:                     while (sourceBytes > 0);
 228:                 }
 229:             }
 230:             string[] directories = Directory.GetDirectories(SourceDirectory);
 231:             foreach (string directroy in directories)
 232:             {
 233:                 CompressDir(ParentPath , directroy, s);
 234:             }
 235:  
 236:         }
 237:  
 238:         private static void PrintUsage()
 239:         {
 240:             Console.WriteLine("\t DNNPackager Usage: ");
 241:             Console.WriteLine("\t\t DNNPackager.exe <source-dir> <manifest-file> <target-path>");
 242:         }
 243:         private static void ExitWith(int errorCode, string errorMessage)
 244:         {
 245:             Console.WriteLine("Error Encountered");
 246:             Console.WriteLine(errorMessage);
 247:             System.Environment.Exit(errorCode);
 248:         }
 249:     }
 250: }

 

There you go with the entire source code. I don’t think I’d need to explain the code, its too simple for me to bother (I think). The usage is pretty simple

   1: private static void PrintUsage()
   2:        {
   3:            Console.WriteLine("\t DNNPackager Usage: ");
   4:            Console.WriteLine("\t\t DNNPackager.exe <source-dir> <manifest-file> <target-path>");
   5:        }

 

As an example: DNNPackager.exe "C:\inetpub\DNN5.2\DesktopModules\SpeedBlog" SpeedBlog.dnn "C:\Builds\SpeedBlog\TEMPBUILD" would create a SpeedBlog_<version>.zip installer file from the SpeedBlog.dnn manifest into the current directory.  A word for the reference. SharpZipLib is in DNN bin directory.

Let me know in comments if this helps anyone out there. Or if I missed anything. Even if I did something entirely unnecessary. And yeah, I need some kind of DNN documentation.

  
 You may also be interested in
  
Locations of visitors to this page Clicky Web Analytics 

Subodh's Blog Rating

 

DISCLAIMER

The opinion expressed
on this page 
is strictly that
of the page author
who has a
habit of animating
day-dreaming
and
fictionalizing
out of thin air.
 

The contents of this page
have not been
reviewed 
nor
approved
by 
Yahoo!

 Follow this blog
  
 Tag Cloud
  
Archives
 

Top 5 Posts of Last year
Copyright © 1995-2009 Subodh Shakya. All rights reserved.{Powered by SpeedBlog}