protected override void ImportTypeLibrary()
        {
            TlbImpTask tlbImp = new TlbImpTask();

            // parent is solution task
            tlbImp.Parent = SolutionTask;

            // inherit project from solution task
            tlbImp.Project = SolutionTask.Project;

            // inherit namespace manager from solution task
            tlbImp.NamespaceManager = SolutionTask.NamespaceManager;

            // inherit verbose setting from solution task
            tlbImp.Verbose = SolutionTask.Verbose;

            // make sure framework specific information is set
            tlbImp.InitializeTaskConfiguration();

            tlbImp.TypeLib = new FileInfo(GetTypeLibrary());
            tlbImp.OutputFile = new FileInfo(WrapperAssembly);
            tlbImp.Namespace = TypeLibraryName;

            // according to "COM Programming with Microsoft .NET" (page 59)
            // the /sysarray option should always be set in order to
            // generate wrappers that match those generated by VS.NET
            tlbImp.SysArray = true;

            // transform [out, retval] parameters of methods on dispatch-only
            // interfaces (dispinterfaces) into return values.
            //
            // this only affects .NET 1.1 or higher, as tlbimp does not expose
            // this on .NET 1.0.
            tlbImp.Transform = "dispret";

            // use other imported type libraries to resolve references
            //
            // there's one serious limitation in the current implementation:
            //
            // if type library A references type library B, then we should
            // first import type library B and use a reference to that
            // imported type library when we import type library A.
            //
            // however, we have no way to find out in which order the type
            // libraries should be imported. So only if type library B is
            // first listed in the project file, it will work fine.
            //
            // we should find a way to analyse a type library to determine
            // dependencies on other type libraries
            //
            // according to JR ([email protected]) a possible
            // solution could be to "use TypeLibConverter.ConvertTypeLibToAssembly.
            // This has a callback of type ITypeLibImporterNotifySink, which I
            // speculate allows one to recognize when one type library
            // depends on another. I believe what you have to do is start
            // with an arbitrary type library, and if that type library calls
            // back on the ResolveRef() method, and if that type library is
            // one you were planning to add later, you compile it
            // immediately and pass the assembly back out of ResolveRef. I
            // haven't tested this yet, but it's my best understanding of
            // how it all works.
            foreach (ReferenceBase reference in Parent.References) {
                // we're only interested in imported type libraries
                WrapperReferenceBase wrapper = reference as WrapperReferenceBase;

                // avoid stack overflow causes by mutual dependencies
                if (wrapper == null || !wrapper.IsCreated || wrapper.WrapperTool != "tlbimp") {
                    continue;
                }

                tlbImp.References.Includes.Add(wrapper.WrapperAssembly);
            }

            if (ProjectSettings.AssemblyOriginatorKeyFile != null) {
                tlbImp.KeyFile = new FileInfo(FileUtils.CombinePaths(Parent.ProjectDirectory.FullName,
                    ProjectSettings.AssemblyOriginatorKeyFile));
            }

            if (ProjectSettings.AssemblyKeyContainerName != null) {
                tlbImp.KeyContainer = ProjectSettings.AssemblyKeyContainerName;
            }

            // increment indentation level
            tlbImp.Project.Indent();
            try {
                // execute task
                tlbImp.Execute();
            } finally {
                // restore indentation level
                tlbImp.Project.Unindent();
            }
        }
Пример #2
0
        protected override void ImportTypeLibrary()
        {
            TlbImpTask tlbImp = new TlbImpTask();

            // parent is solution task
            tlbImp.Parent = SolutionTask;

            // inherit project from solution task
            tlbImp.Project = SolutionTask.Project;

            // inherit namespace manager from solution task
            tlbImp.NamespaceManager = SolutionTask.NamespaceManager;

            // inherit verbose setting from solution task
            tlbImp.Verbose = SolutionTask.Verbose;

            // make sure framework specific information is set
            tlbImp.InitializeTaskConfiguration();

            tlbImp.TypeLib = new FileInfo(GetTypeLibrary());
            tlbImp.OutputFile = new FileInfo(WrapperAssembly);

            // use other imported type libraries to resolve references
            //
            // there's one serious limitation in the current implementation:
            //
            // if type library A references type library B, then we should
            // first import type library B and use a reference to that
            // imported type library when we import type library A.
            //
            // however, we have no way to find out in which order the type
            // libraries should be imported. So only if type library B is
            // first listed in the project file, it will work fine.
            //
            // we should find a way to analyse a type library to determine
            // dependencies on other type libraries
            //
            // according to JR ([email protected]) a possible
            // solution could be to "use TypeLibConverter.ConvertTypeLibToAssembly.
            // This has a callback of type ITypeLibImporterNotifySink, which I
            // speculate allows one to recognize when one type library
            // depends on another. I believe what you have to do is start
            // with an arbitrary type library, and if that type library calls
            // back on the ResolveRef() method, and if that type library is
            // one you were planning to add later, you compile it
            // immediately and pass the assembly back out of ResolveRef. I
            // haven't tested this yet, but it's my best understanding of
            // how it all works.
            foreach (ReferenceBase reference in Parent.References) {
                // we're only interested in imported type libraries
                WrapperReferenceBase wrapper = reference as WrapperReferenceBase;

                // avoid stack overflow causes by mutual dependencies
                if (wrapper == null || !wrapper.IsCreated || wrapper.WrapperTool != "tlbimp") {
                    continue;
                }

                tlbImp.References.Includes.Add(wrapper.WrapperAssembly);
            }

            // increment indentation level
            tlbImp.Project.Indent();
            try {
                // execute task
                tlbImp.Execute();
            } finally {
                // restore indentation level
                tlbImp.Project.Unindent();
            }
        }