一个查看类型库(Type Library)详细信息的工具


        在用C#操作Excel作报表的时候,你可能遇到这样的困扰(用其他COM时也存在类似的问题):引用的组件是哪个版本的Office提供的;想使用tlbimp得到excel.dll,却不知道对哪个文件执行tlbimp(Excel9.olb或Excel.exe)。对于前者我自己深有体会:Office XP以后的版本比Office 2000提供的一些方法的参数要多(比如Excel.Workbooks.Open方法),而且引用Office XP以后版本的dll的.NET应用程序在安装Office 2000的系统上可能会出问题(我遇到过由Excel._Worksheet CurSheet = (Excel._Worksheet)WorkBook.Sheets[1];引发的null值问题),另外,不同版本的Excel引发的客户操作也可能是不同的,如果引用Office 2000下的dll后使用Excel.Workbooks[0].Worksheets[0].Delete()方法删除一个sheet时,会弹出以下对话框:

而引用Office XP以后版本的dll就不会出现这个对话框。 

        我们在C# Project中添加引用时,可以看到下面这个对话框:

        这个对话框列举了当前系统中所有的COM组件,但是它提供的关于类型库的信息并不详细,而且没有搜索功能,用起来不是很方便。
        其实,类型库的信息存储在注册表的HKEY_CLASSES_ROOT->TypeLib下:

        我们可以使用Microsoft.Win32.RegistryKey类来获取这些信息:

        搜索:

        类型库详细信息:

        代码下载:Down 

        下载内容包括:

 

        TypeLibs的详细内容:

  1using System;
  2
  3namespace TypeLibBrowser
  4{
  5    /// <summary>
  6    /// TypeLibs 的摘要说明。
  7    /// </summary>

  8    public class TypeLibs : System.Collections.CollectionBase
  9    {
 10        public TypeLibs()
 11        {
 12            //
 13            // TODO: 在此处添加构造函数逻辑
 14            //
 15        }

 16
 17        private string Obj2Str(object pObj)
 18        {
 19            if (pObj == null)
 20                return String.Empty;
 21            else
 22                return pObj.ToString();
 23        }

 24
 25        public void GetTL()
 26        {
 27            const string ROOT_TLB = "TypeLib";
 28
 29            Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot;
 30            Microsoft.Win32.RegistryKey regTLibRoot = regKey.OpenSubKey(ROOT_TLB);
 31
 32            foreach(string strTypeLib in regTLibRoot.GetSubKeyNames())
 33            {
 34                Microsoft.Win32.RegistryKey regTL = regTLibRoot.OpenSubKey(strTypeLib);
 35                foreach(string strVersion in regTL.GetSubKeyNames())
 36                {
 37                    Microsoft.Win32.RegistryKey regVersion = regTL.OpenSubKey(strVersion);
 38                    TypeLibBrowser.TypeLib typeLib = new TypeLib();
 39                    typeLib.GUID = strTypeLib;
 40                    typeLib.Version = strVersion;
 41                    foreach(string strValueName in regVersion.GetValueNames())
 42                    {
 43                        switch (strValueName)
 44                        {
 45                            case "PrimaryInteropAssemblyName" :
 46                                typeLib.PrimaryInteropAssemblyName = this.Obj2Str(regVersion.GetValue(strValueName));
 47                                break;
 48                            default :
 49                                typeLib.FullName = this.Obj2Str(regVersion.GetValue(strValueName));
 50                                break;
 51                        }

 52                    }

 53                    foreach(string strSubKey in regVersion.GetSubKeyNames())
 54                    {
 55                        Microsoft.Win32.RegistryKey regSubKey = regVersion.OpenSubKey(strSubKey);
 56                        switch (strSubKey)
 57                        {
 58                            case "FLAGS" :
 59                                typeLib.Flags = this.Obj2Str(regSubKey.GetValue(""));
 60                                break;
 61                            case "HELPDIR" :
 62                                typeLib.HelpDir = this.Obj2Str(regSubKey.GetValue(""));
 63                                break;
 64                            default :
 65                                TypeLibBrowser.TLBFiles typeLibFiles = new TLBFiles();
 66                                foreach(string strPlatform in regSubKey.GetSubKeyNames())
 67                                {
 68                                    TypeLibBrowser.TLBFile tlbFile = new TLBFile();
 69                                    tlbFile.Number = strSubKey;
 70                                    switch (strPlatform.Trim().ToUpper())
 71                                    {
 72                                        case "WIN16" :
 73                                            tlbFile.Platform = TypeLibBrowser.TypeLibraryPlatformType.Win16;
 74                                            break;
 75                                        case "WIN32" :
 76                                            tlbFile.Platform = TypeLibBrowser.TypeLibraryPlatformType.Win32;
 77                                            break;
 78                                        case "WIN64" :
 79                                            tlbFile.Platform = TypeLibBrowser.TypeLibraryPlatformType.Win64;
 80                                            break;
 81                                        default :
 82                                            tlbFile.Platform = TypeLibBrowser.TypeLibraryPlatformType.未知;
 83                                            break;
 84                                    }

 85                                    tlbFile.File = this.Obj2Str(regSubKey.OpenSubKey(strPlatform).GetValue(""));                    
 86                                    typeLibFiles.Add(tlbFile);
 87                                }

 88                                typeLib.Files = typeLibFiles;
 89                                break;
 90                        }

 91                    }

 92                    List.Add(typeLib);
 93                }

 94            }

 95        }

 96
 97        /// <summary>
 98        /// 根据GUID和Version搜索Type Library
 99        /// </summary>
100        /// <param name="pGUID"></param>
101        /// <param name="pVersion"></param>
102        /// <returns></returns>

103        public TypeLibBrowser.TypeLib GetTLDetail(string pGUID, string pVersion)
104        {
105            if (this.InnerList.Count == 0)
106                this.GetTL();
107
108            foreach (TypeLibBrowser.TypeLib t in this.InnerList)
109                if (pGUID == t.GUID && pVersion == t.Version)
110                    return t;
111
112            return null;
113        }

114    }

115}

116

        再回到本文开头提出的两个问题,我们可以发现在“详细信息”中包含了我们想知道的答案。

        BTW:微软为Excel VBA提供的帮助本身就包含两个版本:2000和2002的,2003的应该与2002的相同,需要这个帮助(包括VBA For Access 2000、Excel 2000 、Excel 2002、Outlook 2000、Outlook 2002、Word 2000、Word 2002的资料)的朋友可以留下自己的Email,文件有点大,我无法上传,这些帮助对我们使用C#操作Office大有裨益!
        
       

Life is like a boat, and I'm at sea.

posted @ 2005-12-22 13:28 蜡人张 阅读(2443) 评论(22)  编辑 收藏 网摘 所属分类: C#COM & COM+Coding ImageToys

  回复  引用  查看    
#1楼2005-12-22 13:48 | Laser.NET      
多谢提供这样的小工具。
另外对VBA挺感兴趣,但是了解的不够,希望能够得到楼主的一份相关帮助文档。
laser_lu@163.com。在此谢过!

  回复  引用  查看    
#2楼2005-12-22 14:02 | 死死      
<>..'"<ad>&nbsp;
  回复  引用  查看    
#3楼[楼主]2005-12-22 23:57 | 蜡人张      
@Laser.NET:
邮件已发,您是我刚来CnBlogs时的偶像之一呢,呵呵,谢谢您的支持!

  回复  引用  查看    
#4楼2005-12-23 09:35 | 秋天的云      
gyf19@163.com
谢谢,大侠

  回复  引用    
#5楼2005-12-23 09:39 | lost0[未注册用户]
发我一份吧高手
huranyizhou@gmail.com

  回复  引用  查看    
#6楼2005-12-23 10:10 | 妖居      
down了,非常支持!
但是好像发现了一个小问题。
btnSearch_Click函数里面,foreach(TypeLibBrowser.TypeLib tlb in this.tlbList)循环,tlb.FullName有可能是null的。我这里就有一个组件fullname = null。
所以我加了一个tlb.FullName != null的判断在前面。

不知道这个算不算bug。 ^_^

  回复  引用  查看    
#7楼[楼主]2005-12-23 12:28 | 蜡人张      
@妖居:
谢谢您的反馈,确实存在这样的问题。

  回复  引用  查看    
#8楼2005-12-23 13:11 | 简单生活      
我也想要一份,谢谢!
lyi@vip.163.com

  回复  引用  查看    
#9楼2005-12-23 15:44 | 一滴水      
yidishui1570@gmail.com谢谢了
  回复  引用    
#10楼2005-12-26 12:55 | cjh[未注册用户]
maple-2003@sohu.com
谢谢啦

  回复  引用    
#11楼2005-12-26 12:55 | cjh[未注册用户]
maple-2003@sohu.com
谢谢啦

  回复  引用  查看    
#12楼[楼主]2005-12-27 00:06 | 蜡人张      
@cjh:
sohu邮箱无法接收我发送的邮件——maple-2003@sohu.com SMTP error, DOT: 552 Error: message too large

  回复  引用    
#13楼2006-01-09 21:57 | 谢谢[未注册用户]
zhz3996@163.com
  回复  引用    
#14楼2006-03-08 10:27 | 康风光[未注册用户]
急需,谢谢!windglory@163.com
  回复  引用    
#15楼2006-03-10 12:07 | 沈鹏[未注册用户]
需要,非常感谢!shenpeng1024@gmail..com
  回复  引用    
#16楼2006-03-10 12:07 | 沈鹏[未注册用户]
需要,非常感谢!shenpeng1024@gmail.com
  回复  引用    
#17楼2006-07-06 10:49 | yinwer[未注册用户]
的确碰到了OFFICE2000那个SHEET DELETE对话框,赫赫,多谢
yinwer@gmail.com

  回复  引用    
#18楼2006-10-06 23:31 | 烟花古楼[未注册用户]
可以传一个我吗?
lundoo@163.com
94355535@qq.com

  回复  引用    
#19楼2006-10-06 23:31 | 烟花古楼[未注册用户]
可以传一个我吗?
lundoo@163.com
94355535@qq.com

  回复  引用    
#20楼2006-10-06 23:31 | 烟花古楼[未注册用户]
可以传一个我吗?
lundoo@163.com
94355535@qq.com

  回复  引用  查看    
#21楼[楼主]2006-10-08 09:47 | 蜡人张      
@烟花古楼
sorry,这个资料我丢了,以前是在网上下的,你可以搜搜看。:)

  回复  引用    
#22楼2007-04-25 09:29 | apple[未注册用户]
谢谢apple20001130@yahoo.com.cn



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 302519




相关文章:

相关链接: