// 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 // // Giuseppe Greco (giuseppe.greco@agamura.com) using System.Globalization; using System.IO; using System.Text; using NAnt.Core; using NAnt.Core.Tasks; using NAnt.Core.Attributes; using NAnt.Core.Types; using NAnt.Core.Util; using NAnt.DotNet.Tasks; namespace NAnt.DotNet.Tasks { /// /// Signs delay-signed .NET Assemblies, or re-signs existing assemblies. /// /// /// /// The delay-signing mechanism takes a fileset (named targets) /// and either a attribute for a file containing the /// public and private keys, or to name a key /// container. /// /// /// /// Sign partially-signed foo.dll with bar.snk. /// /// /// /// /// /// /// ]]> /// /// [TaskName("delay-sign")] [ProgramLocation(LocationType.FrameworkSdkDir)] public class DelaySignTask : ExternalProgramBase { #region Private Instance Fields private FileSet _targets = new FileSet(); private FileInfo _keyFile; private string _keyContainer; private StringBuilder _argumentBuilder; #endregion Private Instance Fields #region Public Instance Properties /// /// List of assemblies/executables to sign. /// [BuildElement("targets")] public FileSet Targets { get { return _targets; } set { _targets = value; } } /// /// Specifies the filesystem path to the signing key. /// [TaskAttribute("keyfile")] public FileInfo KeyFile { get { return _keyFile; } set { _keyFile = value; } } /// /// Specifies the key container. /// [TaskAttribute("keycontainer")] public string KeyContainer { get { return _keyContainer; } set { _keyContainer = StringUtils.ConvertEmptyToNull(value); } } #endregion Public Instance Properties #region Override implementation of ExternalProgramBase /// /// Gets the command line arguments for the external program. /// /// /// The command line arguments for the external program. /// public override string ProgramArguments { get { if (_argumentBuilder != null) { return _argumentBuilder.ToString(); } else { return null; } } } /// /// Converts a single file or group of files. /// protected override void ExecuteTask() { bool keyAvail = KeyFile != null; bool containerAvail = KeyContainer != null; string keyname = containerAvail ? KeyContainer : KeyFile.FullName; // ensure base directory is set, even if fileset was not initialized // from XML if (Targets.BaseDirectory == null) { Targets.BaseDirectory = new DirectoryInfo(Project.BaseDirectory); } if ((keyAvail && containerAvail) || (! keyAvail && ! containerAvail)) { throw new BuildException(ResourceUtils.GetString("NA2012"), Location); } Log(Level.Info, ResourceUtils.GetString("String_DelaySigningAssemblies"), Targets.FileNames.Count); foreach (string filename in Targets.FileNames) { // Try to guess the buffer length // Add 12 for "-R", maybe 'c' and "-q", and spaces/quotes. _argumentBuilder = new StringBuilder(9 + filename.Length + keyname.Length); if (!Verbose) { _argumentBuilder.Append("-q "); } // indicate that we want to resign a previously signed or delay-signed assembly _argumentBuilder.Append("-R"); if (containerAvail) { _argumentBuilder.Append('c'); } _argumentBuilder.Append(" \"").Append(filename).Append("\" \""); _argumentBuilder.Append(keyname).Append('\"'); // call base class to do perform the actual call base.ExecuteTask(); } } #endregion Override implementation of ExternalProgramBase } }