using System;
using System.Diagnostics;
using System.IO;
using System.Xml;
using NAnt.Core;
using NAnt.Core.Attributes;
namespace My.Build.Tasks
{
[TaskName("publishform")]
public class PublishFormTask : Task
{
[TaskAttribute("outputfolder", Required = true)]
public string OutputFolder { get; set; }
[TaskAttribute("formname", Required = true)]
public string FormName { get; set; }
[TaskAttribute("cabsdkpath", Required = true)]
public string CabSdkPath { get; set; }
[TaskAttribute("xsffilename", Required = true)]
public string XsfFileName { get; set; }
[TaskAttribute("formsourcepath", Required = true)]
public string FormSourcePath { get; set; }
protected override void ExecuteTask()
{
string makeCabPath = CabSdkPath + "\\MAKECAB.EXE";
BuildCabFile(makeCabPath);
}
private void BuildCabFile(string makeCabExe)
{
try
{
if (!File.Exists(makeCabExe))
{
throw new Exception(string.Format("CABSDK not found. Please check your CABSDK property value. Couldn't find makecab.exe @ '{0}'", makeCabExe));
}
var tempName = Path.GetFileNameWithoutExtension(Path.GetTempFileName());
//var tempName = Path.GetTempFileName();
var tempFolder = Path.GetTempPath();
var tempPath = PathCombine(tempFolder, tempName);
var ddfString = string.Empty;
ddfString += ".Set DiskDirectoryTemplate='" + tempFolder + "'" + Environment.NewLine;
ddfString += ".Set CabinetNameTemplate='" + tempName + "'" + Environment.NewLine;
var xsfDom = new XmlDocument();
xsfDom.Load(PathCombine(FormSourcePath, XsfFileName));
var nm = InitNamespaceManager(xsfDom);
ddfString += QuoteString(PathCombine(FormSourcePath, XsfFileName)) + Environment.NewLine;
var fileNodes = xsfDom.SelectNodes("/xsf:xDocumentClass/xsf:package/xsf:files/xsf:file/@name", nm);
for (int i = 0; i <= fileNodes.Count - 1; i++)
{
ddfString += QuoteString(PathCombine(FormSourcePath, fileNodes[i].InnerText)) + Environment.NewLine;
}
var ddfPath = PathCombine(tempFolder, "makecab.ddf");
SaveToFile(ddfString, ddfPath);
ShellExecute(QuoteString(makeCabExe), "/V1 /F " + QuoteString(ddfPath));
File.Delete(ddfPath);
if (File.Exists(PathCombine(OutputFolder, FormName)))
{
File.Delete(PathCombine(OutputFolder, FormName));
}
File.Move(tempPath, PathCombine(OutputFolder, FormName));
string[] oScratchFiles = new string[] { "setup.inf", "setup.rpt" };
foreach (string strScratchFile in oScratchFiles)
{
if (File.Exists(strScratchFile))
{
File.Delete(strScratchFile);
}
}
}
catch (Exception ex)
{
throw new Exception("Could not create XSN file from files.", ex);
}
}
private static void SaveToFile(string data, string filePath)
{
var fs = File.Create(filePath);
fs.Close();
var TextStream = new StreamWriter(filePath);
TextStream.Write(data);
TextStream.Flush();
TextStream.Close();
}
private static void ShellExecute(string command, string args)
{
var info = new ProcessStartInfo(command, args);
info.UseShellExecute = false;
var process = Process.Start(info);
process.WaitForExit(60000);
}
private static string QuoteString(string s)
{
return "\"" + s + "\"";
}
private static string PathCombine(string folder, string fileName)
{
return Path.Combine(folder, fileName);
}
public static XmlNamespaceManager InitNamespaceManager(XmlDocument xmlDOMDoc)
{
XmlNamespaceManager xnmMan;
xnmMan = new XmlNamespaceManager(xmlDOMDoc.NameTable);
foreach (XmlAttribute nsAttr in xmlDOMDoc.DocumentElement.Attributes)
{
if (nsAttr.Prefix == "xmlns")
xnmMan.AddNamespace(nsAttr.LocalName, nsAttr.Value);
}
return xnmMan;
}
public void RunTask()
{
ExecuteTask();
}
}
}