-David Waite
// NAntContrib // Copyright (C) 2003 David Waite // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU Library General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Library General Public License for more details. // // You should have received a copy of the GNU Library General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA using System.Globalization; using System.IO;
using NAnt.Core; using NAnt.Core.Tasks; using NAnt.Core.Attributes; using NAnt.Core.Types; using NAnt.DotNet.Tasks; using StringBuilder = System.Text.StringBuilder; namespace NAnt.Contrib.Tasks { /// <summary> /// Signs Delay-Signed .NET Assemblies, or re-signs existing assemblies. /// </summary> /// <remarks> /// The delay-signing mechanism takes a fileset (named targets) /// and either a 'keyfile' attribute for a file containing the /// public and private keys, or 'container' to name a key container. /// /// The attribute 'quiet' indicates whether the full output should be /// displayed. The default is to suppress all non-error output. /// </remarks> /// <example> /// <para>Sign partially-signed <c>foo.dll</c> with <c>bar.snk</c></para> /// <code> /// <![CDATA[ /// <delay-sign keyfile="bar.snk" quiet='false'> /// <targets> /// <includes name="foo.dll"/> /// </targets> /// </delay-sign> /// ]]> /// </code> /// <para>The parameter keycontainer can also be used.</para> /// </example> [TaskName("delay-sign")] public class DelaySignTask : SdkExternalProgramBase { private FileSet _targets = new FileSet(); private string _keyFilename = null; private string _keyContainer = null; private string _arguments = null; private bool _quiet = true; /// <summary> /// Takes a list of assemblies/executables to sign /// </summary> [FileSet("targets")] public FileSet Targets { get { return _targets; } set { _targets = value; } } /// <summary> /// Specifies the filesystem path to the signing key /// </summary> [TaskAttribute("keyfile")] public string KeyFile { get { return _keyFilename; } set { _keyFilename = value; } } /// <summary> /// Specifies the filesystem path to the signing key /// </summary> [TaskAttribute("keycontainer")] public string KeyContainer { get { return _keyContainer; } set { _keyContainer = value; } } /// <summary> /// Specifies whether non-error output should be suppressed. /// </summary> [TaskAttribute("quiet")] public bool Quiet { get { return _quiet; } set { _quiet = value; } } /// <summary> /// Gets the command line arguments for the external program. /// </summary> /// <value> /// The command line arguments for the external program. /// </value> public override string ProgramArguments { get { return _arguments; } } protected override string ExeName { get { return "sn"; } } /// <summary> /// Converts a single file or group of files. /// </summary> protected override void ExecuteTask() { bool keyAvail = (_keyFilename != null && _keyFilename.Length > 0); bool containerAvail = (_keyContainer != null && _keyContainer.Length > 0); if ((keyAvail && containerAvail) || (!keyAvail && !containerAvail)) { throw new BuildException ("either 'keyfile' or 'keycontainer' must be specified"); } string keyname = (containerAvail ? _keyContainer : _keyFilename); foreach (string filename in Targets.FileNames) { // Try to guess the buffer length // Add 12 for "-R", maybe 'c' and "-q", and spaces/ quotes. StringBuilder arguments = new StringBuilder (9 + filename.Length + keyname.Length); if (Quiet) { arguments.Append("-q "); } arguments.Append("-R"); if (containerAvail) { arguments.Append('c'); } arguments.Append(" \"").Append(filename).Append("\" \""); arguments.Append(keyname).Append('\"'); _arguments = arguments.ToString(); // call base class to do perform the actual call base.ExecuteTask(); } } } }