As part of our push to implement
continuous integration, we need to have
TFS generate
CAB files for us. Unfortunately the only tool we have for this is the archaic piece of crap
CABWIZ and it's not a very friendly tool for automating. What we did was create a
custom build task that calls cabwiz for you and will output the error file back to the build log on failure. Now all we have to do is add this to our
build script:
<CabWiz
InfPath="$(CABFolder)\SDF.INF"
ErrorLog="Error.log"
OutputPath="$(CABFolder)" />
The custom build task looks like this:
namespace OpenNETCF.Build.Utilities
{
using System;
using System.IO;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Microsoft.Win32;
using System.Diagnostics;
/// <summary>
/// Uses CabWiz to create a Smart Device CAB installer.
/// </summary>
/// <example>
/// <code><![CDATA[
/// <CabWiz
/// InfPath="MyApp.inf"
/// ErrorLog="Error.log"
/// WorkingFolder="..\Build"
/// Cpu="x86"
/// Compress="true"
/// NoUninstall="false"
/// OutputPath="..\Release"
/// Platform="wm"
/// PreXml="Pre.xml"
/// PostXml="Post.xml"
/// />
/// ]]></code>
/// </example>
public sealed class CabWiz : ToolTask
{
[Required]
public string InfPath { get; set; }
public bool Compress { get; set; }
public string Cpu { get; set; }
public string ErrorLog { get; set; }
public bool NoUninstall { get; set; }
public string OutputPath { get; set; }
public string Platform { get; set; }
public string PostXml { get; set; }
public string PreXml { get; set; }
private static string CabWizSubPath
{
get { return @"SmartDevices\SDK\SDKTools"; }
}
protected override string ToolName
{
get { return "cabwiz.exe"; }
}
public override bool Execute()
{
bool ret = base.Execute();
if (!ret)
{
string path = Path.GetDirectoryName(InfPath);
path = Path.Combine(path, ErrorLog);
if (File.Exists(path))
{
Log.LogMessageFromText(string.Format("!!! BEGIN CABWIZ ERROR FILE DUMP !!!", path), MessageImportance.High);
Log.LogMessagesFromFile(path, MessageImportance.High);
Log.LogMessageFromText(string.Format("!!! END CABWIZ ERROR FILE DUMP !!!", path), MessageImportance.High);
}
else
{
Log.LogMessageFromText(string.Format("CABWIZ: Couldn't find error log at '{0}'", path), MessageImportance.High);
}
}
return ret;
}
protected override string GenerateFullPathToTool()
{
if (String.IsNullOrEmpty(ToolPath))
{
string path = string.Empty;
using (RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\VisualStudio\9.0\Setup\VS", false))
{
if (regKey != null)
{
path = (string)regKey.GetValue("ProductDir");
}
}
ToolPath = Path.Combine(path, CabWizSubPath);
}
return Path.Combine(ToolPath, ToolName);
}
protected override string GenerateCommandLineCommands()
{
GenerateFullPathToTool();
StringBuilder cabWizArgs = new StringBuilder();
cabWizArgs.AppendFormat("\"{0}\" ", InfPath);
if (!string.IsNullOrEmpty(OutputPath))
{
cabWizArgs.AppendFormat("/dest \"{0}\" ", OutputPath);
}
if (!string.IsNullOrEmpty(ErrorLog))
{
cabWizArgs.AppendFormat("/err \"{0}\" ", ErrorLog);
}
if (!string.IsNullOrEmpty(PreXml))
{
cabWizArgs.AppendFormat("/prexml \"{0}\" ", PreXml);
}
if (!string.IsNullOrEmpty(PostXml))
{
cabWizArgs.AppendFormat("/postxml \"{0}\" ", PostXml);
}
if (!string.IsNullOrEmpty(Cpu))
{
cabWizArgs.AppendFormat("/cpu {0} ", Cpu);
}
if (!string.IsNullOrEmpty(Platform))
{
cabWizArgs.AppendFormat("/platform {0} ", Platform);
}
if (Compress)
{
cabWizArgs.Append("/compress ");
}
if (NoUninstall)
{
cabWizArgs.Append("/nouninstall");
}
Log.LogMessage(MessageImportance.High, cabWizArgs.ToString());
return cabWizArgs.ToString();
}
}
}