Windows.NET 下的COM+ 注册和登记问题
小气的神
2002-6-23
Article Type: Tutorial
难度等级:3/9
版本:1.02
Windows.NET迟早会是一个每日之星,我象喜欢Windows 2000一样的喜欢这个还未发布的操作系统,尽管不知道它会被拖延到明年的什么时候才会真正发布。COM+ 1.5+ 和IIS 6让人期待已久了,一些文章和资料已经开始讨论和介绍一些有关所谓内幕的信息,比如COM+ Partitions, Application recycling, Application pooling ,Configurable Isolation Levels, Low-Memory activation Gates, Http.sys, Web Administration Services, ASP Template caching, XML metabase, MSMQ 3.0 。
可以看到其中的许多功能是致力于改善Web应用程序的强健性和可靠性的,其中的许多特性,让开发人员感到激动和兴奋;相同的感觉让人很容易联想到几年前的Windows 2000发布前的情景,因为相关消息和报道也表明其中的一些特性可能不会放到最终的版本中,同时也可能有一些没有提及的功能会出现在最终的Windows.NET版本中,那么这些迷晦未知的同时也必然会有一些混乱或麻烦的事情让你遇到,比如下面这件。
鉴于Windows.NET的优异性能和dotNET有关COM+的支持,让人会很容易的想移到Windows.NET上,它是如此地稳定如此的稳定,直到有一天,你将在Windows 2000下用dotNET开发的COM+应用放到Windows.NET上,你会发现问题来了。而且很头痛,不过这里也是揭示Windows.NET虽然有.NET的后缀,但并不意味着它对dotNET技术的友好和完全支持,相对dotNET,它更喜欢COM+和IIS,如果不是它的老板一定要给它预装dotNET的运行库,我想叫它 Windows 2002 或 Windows 2003会更好,这样至少不会让人以为它是一个for dotNET的操作系统。
.NET SDK 中有两个工具是和COM+组件的登记和类型库有关的,一个是Assembly Registration Tool ( regasm.exe )另一个是 .NET Services Installation Tool (Regsvcs.exe);在Windows 2000下, 一般我们完成一个dotNET的COM+组件后,会先运行regasm产生类型库和注册信息,然后再运行Regsvcs.exe来完成向COM+环境中添加新的Application的工作,从而完成整个的安装和登记任务。一些人建议直接使用regsvcs.exe 就可以了,因为Regsvcs.exe会自动的调用regasm.exe,理论上一般它会做这样三件事:
1. 它登记一个CLR assembly 为一个COM组件(等于你运行 regasm.exe)
2. 它产生一个COM类型库,在部署你的dotNET组件到一个COM+目录[COM+ catalog]时会使用这个类型库(等于你运行tlbexp.exe ),并且从你assembly中获得ApplicationName和ApplicationActivation等属性在COM+ Catalog中建立一个Application。
3. 最后它使用.NET reflection APIs从你的assembly中获得每个类的属性信息,从而更新COM+ catalog中的每个类的属性设置,使得每个类和你编程时设置Attribute的相同。
这些步骤在Windows 2000的环境中工作的非常顺利,但当你将这些COM+放到Windows.NET的环境下想同样的将它注册到Windows.NET的COM+ Catalog时,就会遇到麻烦,产生一个错误,结果,什么都没有注册,或说你无法完成注册过程。
从Event viewer 中你可以看到更详细的一些dump,但是我保证对你没有任何帮助,我曾将这些信息放到网络上的新闻组和BBS中,当然也包括Microsoft的。有不少网友证实他们在自己的环境下可以恢复和重现这个错误,但似乎没有提供任何解决的办法,终于我开始等待Microsoft有关Windows.NET的Patch了,从Windows.NET 3604开始到3615,3621几乎这些Windows.NET的三个版本都存在同样的问题,最近又有两个新的版本号的Windows.NET测试版发布,不过我已经有些厌倦了不断在这些系统上安装应用软件的过程,所以不能证实后两个版本是否已经解决了:)
System.EnterpriseServices.RegistrationException: Unable to open COM+ 1.0 catalog to configure components. ---> System.Runtime.InteropServices.COMException (0xC0000005): Exception from HRESULT: 0xC0000005.
at System.EnterpriseServices.Admin.ICatalog.GetCollection(String bstrCollName)
at System.EnterpriseServices.RegistrationDriver.PrepDriver(ApplicationSpec& spec)
--- End of inner exception stack trace ---
Server stack trace:
at System.EnterpriseServices.RegistrationDriver.InstallAssembly(String assembly, String& application, String partition, String& tlb, InstallationFlags installFlags, Object obSync)
at System.EnterpriseServices.RegistrationHelperTx.InstallAssembly(String assembly, String& application, String partition, String& tlb, InstallationFlags installFlags, Object sync)
at System.Runtime.Remoting.Messaging.Message.Dispatch(Object target, Boolean fExecuteInContext)
at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at System.EnterpriseServices.RegistrationHelperTx.InstallAssembly(String assembly, String& application, String partition, String& tlb, InstallationFlags installFlags, Object sync)
at System.EnterpriseServices.RegistrationHelper.TryTransactedInstall(String assembly, String& application, String partition, String& tlb, InstallationFlags installFlags)
at System.EnterpriseServices.RegistrationHelper.InstallAssembly(String assembly, String& application, String partition, String& tlb, InstallationFlags installFlags)
at System.EnterpriseServices.Internal.ComManagedImportUtil.InstallAssembly(String asmpath, String parname, String appname) |
如果你也曾遇到相同的问题(或是在Windows XP上,我没有安装和使用过任何XP的版本,所以不知道Windows XP下是否有这样的问题,如果没有,那么你将是多么地幸福),现在有一个简单的办法可以解决这个问题,Roman Kiss在codeproject上有一篇文章是关于.Net/COM+ Installation Tool,这篇文章早就有了,dotNET Beta2时期,我最近才发现并联想它可能可以解决所遇到的问题。
在Microsoft没有发布新的Patch前可以用两种方法来解决这个问题:
1. 先在Windows 2000的环境下将其安装和调试完毕,然后Export这些Application到一个msi的安装包中,然后在Windows.NET的环境中安装这个包。这种方法可以避免发生这样的问题,但是很不稳定,也就是说有时你可以成功安装,有时你不能。另外如果你是的开发环境或其它的应用是在Windows.NET上,你会感到非常的不适应和沮丧,频繁的切换于两个系统和不停的打包安装可以让你忘了真正要做的是什么。
2. 另一种方式是写一个自己的Regsvcs程序来完成登记的过程,因为从错误信息来看,显示是dotNET的Regsvcs程序和Windows.NET下的COM+ catalog API有问题,也许现在的Regsvcs只认1.0的API,而Windows.NET至少是1.5的了。我也试图这么做了,简单的Sample或是API手册让我很快的恢复了使用Regsvcs时相同的错误,唯一不同的是现在可以单步debug,知道出错在那一个语句了。直到我看到Roman Kiss的文章,我终于知道正确的方式是怎样的了。
下面是解决的步骤:
1. 先去 [CodeProject 96.4K] 获得这个project程序,解压缩后,删除COMAdmin的引用,添加一个新的Windows.NET COMAdmin引用库,然后编译整个Project。最后你会得到一个Regasm2.exe的程序,这就是一个新的Regsvcs注册程序。
2. 切换到project中的测试程序目录进行注册。
regasm AttributeTester.dll /tlb:AttributeTester.tlb
regasm2 AttributeTester.dll |
3. 打开Component Services的COM+ Explorer , 你会发现组件已经被正确的注册了,并且Application和每个组件的属性都是依照你程序中设置的那样被设置了,这一点很重要,因为使用上面我说的第一种解决方法(使用倒出的安装包),经常是好不容易安装组件包成功,但是发现这些属性信息没有被正确的设置,更多的属性是空白的。(类似的情况也发生在从Windows.NET的COM+中倒出的组件安装包,重新安装到Windows 2000的环境中,理论上Windows.NET支持另外更高版本的安装包格式,因为倒出时Windows.NET允许你选择是否兼容COM+ Admin 1.0的格式)
4. 最后我们简单的测试一下,看这种方式下是否正确的工作了,我简单的使用OLE/COM Object Viewer,它有一个好处,就是现在所有的CLR assembly被注册到COM+中,你在这个工具中可以看到它会自动的被归类到Grouped by Component category -> .NET Category中,这样就很方便的可以找到你的组件。选中组件,然后点右键在菜单中选择Create Instance就可以简单地测试它是否运行正常了。
5. 看来结果好像还不错,正是我们想要的,从DebugView中Dump出的信息,正是我们download的代码中特意要输出的信息。
我不知道这是否是一个愉快之旅,但我的确可以不用为Windows.NET下有关COM+组件登记注册的事情再烦恼了。最后发布的Windows.NET一定没有这个问题,所以在这之前的一段时间,我想,正如广州现在的天气,可以用一个词来形容:郁闷。还好网络上没有下雨的阴闷,而且总有一些让你感到轻松的人,所以一定要感谢Roman Kiss。
|