Thursday, September 18, 2008
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();
    }
  }
}


9/18/2008 10:22:34 AM (Eastern Daylight Time, UTC-04:00)  #    Comments [1]  | 
4/22/2009 10:56:06 AM (Eastern Daylight Time, UTC-04:00)
Hi Chris,
Do you have a solution to Create inf files on the Fly? or how do you maintain the inf files?
BR
Daniel
Name
E-mail
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):