// 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
//
// Aaron Anderson (aaron@skypoint.com | aaron.anderson@farmcreditbank.com)
using System.Collections.Specialized;
using System.IO;
using System.Text;
using NAnt.Core;
using NAnt.Core.Attributes;
using NAnt.Core.Tasks;
using NAnt.Core.Types;
using NAnt.Core.Util;
namespace NAnt.Win32.Tasks {
///
/// Exports a .NET assembly to a type library that can be used from unmanaged
/// code (wraps Microsoft's tlbexp.exe).
///
///
///
/// See the Microsoft.NET Framework SDK documentation for details.
///
///
///
/// Export DotNetAssembly.dll to LegacyCOM.dll.
///
///
/// ]]>
///
///
[TaskName("tlbexp")]
[ProgramLocation(LocationType.FrameworkSdkDir)]
public class TlbExpTask : ExternalProgramBase {
#region Private Instance Fields
private FileInfo _assemblyFile;
private FileInfo _outputFile;
private FileInfo _namesFile;
private StringBuilder _argumentBuilder;
#endregion Private Instance Fields
#region Public Instance Properties
///
/// Specifies the assembly for which to export a type library.
///
///
/// The assembly for which to export a type library.
///
/// See the Microsoft.NET Framework SDK documentation for details.
[TaskAttribute("assembly", Required=true)]
public FileInfo AssemblyFile {
get { return _assemblyFile; }
set { _assemblyFile = value; }
}
///
/// Specifies the name of the type library file to generate.
///
///
/// The name of the type library file to generate.
///
/// See the Microsoft.NET Framework SDK documentation for details.
[TaskAttribute("output", Required=true)]
public FileInfo OutputFile {
get { return _outputFile; }
set { _outputFile = value; }
}
///
/// Specifies the file used to determine capitalization of names in a
/// type library.
///
///
/// The file used to determine capitalization of names in a type library.
///
/// See the Microsoft.NET Framework SDK documentation for details.
[TaskAttribute("names")]
public FileInfo NamesFile {
get { return _namesFile; }
set { _namesFile = 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;
}
}
}
///
/// Exports the type library.
///
protected override void ExecuteTask() {
//Check to see if any of the underlying interop dlls or the typelibs have changed
//Otherwise, it's not necessary to reimport.
if (NeedsCompiling()) {
//Using a stringbuilder vs. StreamWriter since this program will not accept response files.
_argumentBuilder = new StringBuilder();
_argumentBuilder.Append("\"" + AssemblyFile.FullName + "\"");
// Any option that specifies a file name must be wrapped in quotes
// to handle cases with spaces in the path.
_argumentBuilder.AppendFormat(" /out:\"{0}\"", OutputFile.FullName);
// suppresses the Microsoft startup banner display
_argumentBuilder.Append(" /nologo");
if (Verbose) {
// displays extra information
_argumentBuilder.Append(" /verbose");
} else {
// suppresses all output except for errors
_argumentBuilder.Append(" /silent");
}
// filename used to determine capitalization of names in typelib
if (NamesFile != null) {
_argumentBuilder.AppendFormat(" /names:\"{0}\"", NamesFile.FullName);
}
// call base class to do the work
base.ExecuteTask();
}
}
#endregion Override implementation of ExternalProgramBase
#region Protected Instance Methods
///
/// Determines whether the assembly needs to be exported to a type
/// library again.
///
///
/// if the assembly needs to be exported to a
/// type library; otherwise, .
///
protected virtual bool NeedsCompiling() {
// return true as soon as we know we need to compile
if (!OutputFile.Exists) {
Log(Level.Verbose, "Output file '{0}' does not exist, recompiling.",
OutputFile.FullName);
return true;
}
// check if the assembly was changed since the typelib was generated
string fileName = FileSet.FindMoreRecentLastWriteTime(AssemblyFile.FullName, OutputFile.LastWriteTime);
if (fileName != null) {
Log(Level.Verbose, "'{0}' has been updated, recompiling.",
fileName);
return true;
}
// check if the names file was changed since the typelib was generated
if (NamesFile != null) {
fileName = FileSet.FindMoreRecentLastWriteTime(NamesFile.FullName, OutputFile.LastWriteTime);
if (fileName != null) {
Log(Level.Verbose, "'{0}' has been updated, recompiling.",
fileName);
return true;
}
}
// if we made it here then we don't have to export the assembly again.
return false;
}
#endregion Protected Instance Methods
}
}