Logo Search packages:      
Sourcecode: nant version File versions  Download package

TlbImpTask.cs

// 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
//
// Gerry Shaw (gerry_shaw@yahoo.com)
// Aaron Anderson (gerry_shaw@yahoo.com)
// Ian MacLean (ian@maclean.ms)

using System.Collections.Specialized;
using System.IO;
using System.Text;

using NAnt.DotNet.Types;

using NAnt.Core;
using NAnt.Core.Attributes;
using NAnt.Core.Tasks;
using NAnt.Core.Types;
using NAnt.Core.Util;

namespace NAnt.Win32.Tasks {
    /// <summary>
    /// Imports a type library to a .NET assembly (wraps Microsoft's <c>tlbimp.exe</c>).
    /// </summary>
    /// <remarks>
    /// <para>
    /// This task lets you easily create interop assemblies.  By default, it will 
    /// not reimport if the underlying COM TypeLib or reference has not changed.
    /// </para>
    /// <para>
    /// <see href="ms-help://MS.NETFrameworkSDK/cptools/html/cpgrftypelibraryimportertlbimpexe.htm">See the Microsoft.NET Framework SDK documentation for details.</see>
    /// </para>
    /// </remarks>
    /// <example>
    ///   <para>Import <c>LegacyCOM.dll</c> to <c>DotNetAssembly.dll</c>.</para>
    ///   <code>
    ///     <![CDATA[
    /// <tlbimp typelib="LegacyCOM.dll" output="DotNetAssembly.dll" />
    ///     ]]>
    ///   </code>
    /// </example>
    [TaskName("tlbimp")]
    [ProgramLocation(LocationType.FrameworkSdkDir)]
00057     public class TlbImpTask : ExternalProgramBase {
        #region Private Instance Fields

        private FileInfo _outputFile;
        private string _namespace;
        private string _asmVersion;
        private bool _delaySign;
        private bool _primary;
        private FileInfo _publicKeyFile;
        private FileInfo _keyFile;
        private string _keyContainer;
        private AssemblyFileSet _references = new AssemblyFileSet();
        private bool _strictref;
        private bool _sysarray;
        private bool _unsafe;
        private FileInfo _typelib;
        private StringBuilder _argumentBuilder;

        #endregion Private Instance Fields

        #region Public Instance Properties

        /// <summary>
        /// Specifies the name of the output file.
        /// </summary>
        /// <value>
        /// The name of the output file.
        /// </value>
        /// <remarks><a href="ms-help://MS.NETFrameworkSDK/cptools/html/cpgrftypelibraryimportertlbimpexe.htm">See the Microsoft.NET Framework SDK documentation for details.</a></remarks>
        [TaskAttribute("output", Required=true)]
00087         public FileInfo OutputFile {
            get { return _outputFile; }
            set { _outputFile = value; }
        }

        /// <summary>
        /// Specifies the namespace in which to produce the assembly.
        /// </summary>
        /// <value>
        /// The namespace in which to produce the assembly.
        /// </value>
        /// <remarks><a href="ms-help://MS.NETFrameworkSDK/cptools/html/cpgrftypelibraryimportertlbimpexe.htm">See the Microsoft.NET Framework SDK documentation for details.</a></remarks>
        [TaskAttribute("namespace")]
00100         public string Namespace {
            get { return _namespace; }
            set { _namespace = StringUtils.ConvertEmptyToNull(value); }
        }

        /// <summary>
        /// Specifies the version number of the assembly to produce.
        /// </summary>
        /// <remarks>
        /// <value>
        /// The version number of the assembly to produce.
        /// </value>
        /// <para>
        /// The version number should be in the format major.minor.build.revision.
        /// </para>
        /// <para>
        /// <a href="ms-help://MS.NETFrameworkSDK/cptools/html/cpgrftypelibraryimportertlbimpexe.htm">See the Microsoft.NET Framework SDK documentation for details.</a>
        /// </para>
        /// </remarks>
        [TaskAttribute("asmversion")]
00120         public string AsmVersion {
            get { return _asmVersion; }
            set { _asmVersion = StringUtils.ConvertEmptyToNull(value); }
        }

        /// <summary>
        /// Specifies whether the resulting assembly should be signed with a 
        /// strong name using delayed signing. The default is <see langword="false" />.
        /// </summary>
        /// <value>
        /// <see langword="true" /> if the resulting assembly should be signed 
        /// with a strong name using delayed signing; otherwise, <see langword="false" />.
        /// </value>
        /// <remarks><a href="ms-help://MS.NETFrameworkSDK/cptools/html/cpgrftypelibraryimportertlbimpexe.htm">See the Microsoft.NET Framework SDK documentation for details.</a></remarks>
        [TaskAttribute("delaysign")]
        [BooleanValidator()]
00136         public bool DelaySign {
            get { return _delaySign; }
            set { _delaySign = value; }
        }

        /// <summary>
        /// Specifies whether a primary interop assembly should be produced for 
        /// the specified type library. The default is <see langword="false" />.
        /// </summary>
        /// <value>
        /// <see langword="true" /> if a primary interop assembly should be 
        /// produced; otherwise, <see langword="false" />.
        /// </value>
        /// <remarks><a href="ms-help://MS.NETFrameworkSDK/cptools/html/cpgrftypelibraryimportertlbimpexe.htm">See the Microsoft.NET Framework SDK documentation for details.</a></remarks>
        [TaskAttribute("primary")]
        [BooleanValidator()]
00152         public bool Primary {
            get { return _primary; }
            set { _primary = value; }
        }

        /// <summary>
        /// Specifies the file containing the public key to use to sign the 
        /// resulting assembly.
        /// </summary>
        /// <value>
        /// The file containing the public key to use to sign the resulting
        /// assembly.
        /// </value>
        /// <remarks><a href="ms-help://MS.NETFrameworkSDK/cptools/html/cpgrftypelibraryimportertlbimpexe.htm">See the Microsoft.NET Framework SDK documentation for details.</a></remarks>
        [TaskAttribute("publickey")]
00167         public FileInfo PublicKeyFile {
            get { return _publicKeyFile; }
            set { _publicKeyFile = value; }
        }

        /// <summary>
        /// Specifies the publisher's official public/private key pair with which 
        /// the resulting assembly should be signed with a strong name.
        /// </summary>
        /// <value>
        /// The keyfile to use to sign the resulting assembly with a strong name.
        /// </value>
        /// <remarks><a href="ms-help://MS.NETFrameworkSDK/cptools/html/cpgrftypelibraryimportertlbimpexe.htm">See the Microsoft.NET Framework SDK documentation for details.</a></remarks>
        [TaskAttribute("keyfile")]
00181         public FileInfo KeyFile {
            get { return _keyFile; }
            set { _keyFile = value; }
        }

        /// <summary>
        /// Specifies the key container in which the public/private key pair 
        /// should be found that should be used to sign the resulting assembly
        /// with a strong name.
        /// </summary>
        /// <value>
        /// The key container containing a public/private key pair that should
        /// be used to sign the resulting assembly.
        /// </value>
        /// <remarks><a href="ms-help://MS.NETFrameworkSDK/cptools/html/cpgrftypelibraryimportertlbimpexe.htm">See the Microsoft.NET Framework SDK documentation for details.</a></remarks>
        [TaskAttribute("keycontainer")]
00197         public string KeyContainer {
            get { return _keyContainer; }
            set {_keyContainer = StringUtils.ConvertEmptyToNull(value); }
        }

        /// <summary>
        /// Specifies the assembly files to use to resolve references to types 
        /// defined outside the current type library. 
        /// </summary>
        /// <value>
        /// The assembly files to use to resolve references to types defined 
        /// outside the current type library.
        /// </value>
        /// <remarks><a href="ms-help://MS.NETFrameworkSDK/cptools/html/cpgrftypelibraryimportertlbimpexe.htm">See the Microsoft.NET Framework SDK documentation for details.</a></remarks>
        [BuildElement("references")]
00212         public AssemblyFileSet References {
            get { return _references; }
            set { _references = value; }
        }

        /// <summary>
        /// Specifies whether a type library should not be imported if all 
        /// references within the current assembly or the reference assemblies 
        /// cannot be resolved. The default is <see langword="false" />.
        /// </summary>
        /// <value>
        /// <see langword="true" /> if a type library should not be imported if 
        /// all references cannot be resolved; otherwise, <see langword="false" />.
        /// </value>
        /// <remarks><a href="ms-help://MS.NETFrameworkSDK/cptools/html/cpgrftypelibraryimportertlbimpexe.htm">See the Microsoft.NET Framework SDK documentation for details.</a></remarks>
        [TaskAttribute("strictref")]
        [BooleanValidator()]
00229         public bool StrictRef {
            get { return _strictref; }
            set { _strictref = value; }
        }

        /// <summary>
        /// Specifies whether to import a COM style SafeArray as a managed 
        /// <see cref="System.Array" /> class type. The default is <see langword="false" />.
        /// </summary>
        /// <value>
        /// <see langword="true" /> if a COM style SafeArray should be imported 
        /// as a managed <see cref="System.Array" /> class type; otherwise, 
        /// <see langword="false" />.
        /// </value>
        /// <remarks><a href="ms-help://MS.NETFrameworkSDK/cptools/html/cpgrftypelibraryimportertlbimpexe.htm">See the Microsoft.NET Framework SDK documentation for details.</a></remarks>
        [TaskAttribute("sysarray")]
        [BooleanValidator()]
00246         public bool SysArray {
            get { return _sysarray; }
            set { _sysarray = value; }
        }

        /// <summary>
        /// Specifies the source type library that gets passed to the type 
        /// library importer.
        /// </summary>
        /// <value>
        /// The source type library that gets passed to the type library 
        /// importer.
        /// </value>
        /// <remarks><a href="ms-help://MS.NETFrameworkSDK/cptools/html/cpgrftypelibraryimportertlbimpexe.htm">See the Microsoft.NET Framework SDK documentation for details.</a></remarks>
        [TaskAttribute("typelib", Required=true)]
00261         public FileInfo TypeLib {
            get { return _typelib; }
            set { _typelib = value; }
        }

        /// <summary>
        /// Specifies whether interfaces should be produced without .NET Framework 
        /// security checks. The default is <see langword="false" />.
        /// </summary>
        /// <value>
        /// <see langword="true" /> if interfaces without .NET Framework security 
        /// checks should be produced; otherwise, <see langword="false" />.
        /// </value>
        /// <remarks><a href="ms-help://MS.NETFrameworkSDK/cptools/html/cpgrftypelibraryimportertlbimpexe.htm">See the Microsoft.NET Framework SDK documentation for details.</a></remarks>
        [TaskAttribute("unsafe")]
        [BooleanValidator()]
00277         public bool Unsafe {
            get { return _unsafe; }
            set { _unsafe = value; }
        }

        #endregion Public Instance Properties

        #region Override implementation of ExternalProgramBase

        /// <summary>
        /// Gets the command line arguments for the external program.
        /// </summary>
        /// <value>
        /// The command line arguments for the external program.
        /// </value>
00292         public override string ProgramArguments {
            get { 
                if (_argumentBuilder != null) {
                    return _argumentBuilder.ToString();
                } else {
                    return null;
                }
            }
        }

        /// <summary>
        /// Imports the type library to a .NET assembly.
        /// </summary>
00305         protected override void ExecuteTask() {
            // ensure base directory is set, even if fileset was not initialized
            // from XML
            if (References.BaseDirectory == null) {
                References.BaseDirectory = new DirectoryInfo(Project.BaseDirectory);
            }

            // 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("\"" + TypeLib.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 (AsmVersion != null) {
                    _argumentBuilder.AppendFormat(" /asmversion:{0}", AsmVersion);
                }

                if (Namespace != null) {
                    _argumentBuilder.AppendFormat(" /namespace:{0}", Namespace);
                }

                if (Primary) {
                    _argumentBuilder.Append(" /primary");
                }

                if (Unsafe) {
                    _argumentBuilder.Append(" /unsafe");
                }

                if (DelaySign) {
                    _argumentBuilder.Append(" /delaysign");
                }

                if (PublicKeyFile != null) {
                    _argumentBuilder.AppendFormat(" /publickey:\"{0}\"", PublicKeyFile.FullName);
                }

                if (KeyFile != null) {
                    _argumentBuilder.AppendFormat(" /keyfile:\"{0}\"", KeyFile.FullName);
                }

                if (KeyContainer != null) {
                    _argumentBuilder.AppendFormat(" /keycontainer:{0}", KeyContainer);
                }

                if (StrictRef) {
                    _argumentBuilder.Append(" /strictref");
                }

                if (SysArray) {
                    _argumentBuilder.Append(" /sysarray");
                }

                if (Verbose) {
                    // displays extra information
                    _argumentBuilder.Append(" /verbose");
                } else {
                    // suppresses all output except for errors
                    _argumentBuilder.Append(" /silent");
                }

                foreach (string fileName in References.FileNames) {
                    _argumentBuilder.AppendFormat(" /reference:\"{0}\"", fileName);
                }

                // call base class to do the work
                base.ExecuteTask();
            }
        }

        #endregion Override implementation of ExternalProgramBase

        #region Protected Instance Methods

        /// <summary>
        /// Determines whether the type library needs to be imported again.
        /// </summary>
        /// <returns>
        /// <see langword="true" /> if the type library needs to be imported; 
        /// otherwise, <see langword="false" />.
        /// </returns>
00395         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 type library was updated since the interop assembly was generated
            string fileName = FileSet.FindMoreRecentLastWriteTime(TypeLib.FullName, OutputFile.LastWriteTime);
            if (fileName != null) {
                Log(Level.Verbose, "'{0}' has been updated, recompiling.", 
                    fileName);
                return true;
            }

            // check if the reference assemblies were updated since the interop assembly was generated
            fileName = FileSet.FindMoreRecentLastWriteTime(References.FileNames, 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 reimport the typelib.
            return false;
        }

        #endregion Protected Instance Methods
    }
}

Generated by  Doxygen 1.6.0   Back to index