// NAnt - A .NET build tool // Copyright (C) 2001-2003 Gerry Shaw // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU 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 General Public License for more details. // // You should have received a copy of the GNU 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 // // Chris Jenkin (oneinchhard@hotmail.com) // Gerry Shaw (gerry_shaw@yahoo.com) using System; using System.Collections.Specialized; using System.Globalization; using System.IO; using NAnt.Core.Attributes; using NAnt.Core.Types; using NAnt.Core.Util; namespace NAnt.Core.Tasks { /// /// Changes the file attributes of a file or set of files and directories. /// /// /// /// does not have the concept of turning /// attributes off. Instead you specify all the attributes that you want /// turned on and the rest are turned off by default. /// /// /// Refer to the enumeration in the .NET SDK /// for more information about file attributes. /// /// /// /// /// Set the read-only file attribute for the specified file in /// the project directory. /// /// /// /// ]]> /// /// /// /// /// Set the normal file attribute for the specified file. /// /// /// /// ]]> /// /// /// /// /// Set the normal file attribute for all executable files in /// the current project directory and sub-directories. /// /// /// /// /// /// /// /// /// ]]> /// /// [TaskName("attrib")] public class AttribTask : Task { #region Private Instance Fields private FileInfo _file; private FileSet _fileset = new FileSet(); private bool _archiveAttrib; private bool _hiddenAttrib; private bool _normalAttrib; private bool _readOnlyAttrib; private bool _systemAttrib; #endregion Private Instance Fields #region Public Instance Properties /// /// The name of the file which will have its attributes set. This is /// provided as an alternate to using the task's fileset. /// [TaskAttribute("file")] public FileInfo File { get { return _file; } set { _file = value; } } /// /// All the matching files and directories in this fileset will have /// their attributes set. /// [BuildElement("fileset")] public FileSet AttribFileSet { get { return _fileset; } set {_fileset = value; } } /// /// Set the archive attribute. The default is . /// [TaskAttribute("archive")] [BooleanValidator()] public bool ArchiveAttrib { get { return _archiveAttrib; } set { _archiveAttrib = value; } } /// /// Set the hidden attribute. The default is . /// [TaskAttribute("hidden")] [BooleanValidator()] public bool HiddenAttrib { get { return _hiddenAttrib; } set { _hiddenAttrib = value; } } /// /// Set the normal file attributes. This attribute is only valid if used /// alone. The default is . /// [TaskAttribute("normal")] [BooleanValidator()] public bool NormalAttrib { get { return _normalAttrib; } set { _normalAttrib = value; } } /// /// Set the read-only attribute. The default is . /// [TaskAttribute("readonly")] [BooleanValidator()] public bool ReadOnlyAttrib { get { return _readOnlyAttrib; } set { _readOnlyAttrib = value; } } /// /// Set the system attribute. The default is . /// [TaskAttribute("system")] [BooleanValidator()] public bool SystemAttrib { get { return _systemAttrib; } set { _systemAttrib = value; } } #endregion Public Instance Properties #region Override implementation of Task protected override void ExecuteTask() { // ensure base directory is set, even if fileset was not initialized // from XML if (AttribFileSet.BaseDirectory == null) { AttribFileSet.BaseDirectory = new DirectoryInfo(Project.BaseDirectory); } // add the shortcut filename to the file set if (File != null) { AttribFileSet.Includes.Add(File.FullName); } if (AttribFileSet.FileNames.Count > 0) { // determine attributes to set on files FileAttributes fileAttributes = GetFileAttributes(); // display build log message Log(Level.Info, "Setting file attributes for {0} files to {1}.", AttribFileSet.FileNames.Count, fileAttributes.ToString(CultureInfo.InvariantCulture)); // perform operation on files foreach (string path in AttribFileSet.FileNames) { SetFileAttributes(path, fileAttributes); } } if (AttribFileSet.DirectoryNames.Count > 0) { // determine attributes to set on directories FileAttributes directoryAttributes = GetDirectoryAttributes(); // display build log message Log(Level.Info, "Setting attributes for {0} directories to {1}.", AttribFileSet.DirectoryNames.Count, directoryAttributes.ToString(CultureInfo.InvariantCulture)); // perform operation on directories foreach (string path in AttribFileSet.DirectoryNames) { SetDirectoryAttributes(path, directoryAttributes); } } if (AttribFileSet.FileNames.Count == 0 && AttribFileSet.DirectoryNames.Count == 0) { Log(Level.Verbose, "No matching files or directories found."); } } #endregion Override implementation of Task #region Private Instance Methods private FileAttributes GetFileAttributes() { FileAttributes fileAttributes = 0; if (NormalAttrib) { fileAttributes = FileAttributes.Normal; } else { if (ArchiveAttrib) { fileAttributes |= FileAttributes.Archive; } if (HiddenAttrib) { fileAttributes |= FileAttributes.Hidden; } if (ReadOnlyAttrib) { fileAttributes |= FileAttributes.ReadOnly; } if (SystemAttrib) { fileAttributes |= FileAttributes.System; } } if (!Enum.IsDefined(typeof(FileAttributes), fileAttributes)) { fileAttributes = FileAttributes.Normal; } return fileAttributes; } private void SetFileAttributes(string path, FileAttributes fileAttributes) { try { Log(Level.Verbose, path); System.IO.File.SetAttributes(path, fileAttributes); } catch (Exception ex) { string msg = string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("NA1102"), path); if (FailOnError) { throw new BuildException(msg, Location, ex); } else { Log(Level.Verbose, msg + " " + ex.Message); } } } private FileAttributes GetDirectoryAttributes() { FileAttributes directoryAttributes = FileAttributes.Directory; if (!NormalAttrib) { if (ArchiveAttrib) { directoryAttributes |= FileAttributes.Archive; } if (HiddenAttrib) { directoryAttributes |= FileAttributes.Hidden; } if (ReadOnlyAttrib) { directoryAttributes |= FileAttributes.ReadOnly; } if (SystemAttrib) { directoryAttributes |= FileAttributes.System; } } return directoryAttributes; } private void SetDirectoryAttributes(string path, FileAttributes fileAttributes) { try { if (System.IO.Directory.Exists(path)) { Log(Level.Verbose, path); System.IO.File.SetAttributes(path, fileAttributes); } else { throw new DirectoryNotFoundException(); } } catch (Exception ex) { string msg = string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("NA1101"), path); if (FailOnError) { throw new BuildException(msg, Location, ex); } else { Log(Level.Verbose, msg + " " + ex.Message); } } } #endregion Private Instance Methods } }