Ejemplo n.º 1
0
        protected string GetTypeLibrary()
        {
            string typeLibKey = string.Format(CultureInfo.InvariantCulture,
                                              @"TYPELIB\{0}\{1}\{2}\win32", TypeLibGuid, TypeLibVersion,
                                              TypeLibLocale);

            using (RegistryKey registryKey = Registry.ClassesRoot.OpenSubKey(typeLibKey)) {
                // TODO: if there's no direct match, then use a type library
                // with the same major version, and the highest minor version

                // TODO: check if the library identifier matches the one of the
                // reference

                if (registryKey == null)
                {
                    throw CreateTypeLibraryNotRegisteredException();
                }

                string typeLibValue = (string)registryKey.GetValue(null);
                if (StringUtils.IsNullOrEmpty(typeLibValue))
                {
                    throw CreateInvalidTypeLibraryRegistrationException();
                }

                // extract path to type library from reg value
                string typeLibPath = TlbImpTask.ExtractTypeLibPath(typeLibValue);
                // check if the typelib actually exists
                if (!File.Exists(typeLibPath))
                {
                    throw CreateTypeLibraryPathDoesNotExistException(typeLibPath);
                }
                return(typeLibValue);
            }
        }
Ejemplo n.º 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();
            }
        }
Ejemplo n.º 3
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);
            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();
            }
        }