分类: WINDOWS
2008-11-13 21:48:32
WWSDK Beta2 COM实现技术可行性分析
命题: .Net 能够实现为COM对象吗? 和C++/ATL开发的SDKCOM对象交互(互相调用)? 线程模型对实现有影响吗?COMSDK能够较方便的发布给.Net用户吗?
术语说明:
Clientcom.dll , 采用ATL编写的模拟SDk COM包装的COM对象,且是一个单件,且是一个MainSTA。(这儿单件和线程模型的模式有待商榷)
aliim.exe , 它初始化了MainSTA。
Dotnetcom.dll ,C# 编写的实现了ITestPlugin接口的COM对象.
Atlplugincom , 实现为Apart/Free的com组件。
说明:
1. 假定我们的Clientcom标记为MainSTA,创建于主线程, 因此它都运行于MainSTA。不过还是测试了它被在OtherSTA/MTA中创建的表现。
2. 对于套间的判定通过观察线程ID来辅助判断。
3. 插件被假定创建的线程等于Clientcom被创建的线程。
Case 1: 观察dotnetcom 对象的线程模型,dotnet是否能够使用所有的线程模型?
结论: 还没有找到修改其线程模型的方式,通过修改注册从运行结果来看没有效果,从结果来看似乎dotnetcom始终被设置为both。
Case 2 : dotnet可以实现COM接口,可以被回调/通知:
模拟dotnet COM对象实现ITestPlugin后当特定消息发生后得到通知.
前提: 由于aliim.exe 在进入后就call oleinitialize(NULL) 将自己带入了一个MAINSTA。因此测试中不再特别创建套间。
步骤:
1) 由于需要模拟一个合适的ATL COM wrapper ,因此在wwsdk.dll 初始化之后初始化 clientcom.dll.
2) Aliim.exe call clientcom.dll::Test
3) Clientcom.dll::Test 加载dotnetcom.dll 然后寻找ITestPlugin找到后调用OnNotify 来进行消息通知。
结论:
发现不管如何修改 ThreadingModel dotnetcom dll 始终在SameSTA中的到调用。
我还没有找到如何设置dotnetcom dll 如何成为Free/Single,仅仅修改注册表中的值没有达到类似的目的。根据我在forum MSDN上提问的回答,似乎认为在.Net编写的COM中注册表的值仅仅是个提示,可以认为就是等同于Both.
另外,通过重新写了一个atlplugincom.dll 编写为Free模式的组件,这样验证了,运行于Free模型下消息通知同样有效.
|
Clientcom(Create from MAINSTA) |
Dotnetcom(Apartment) |
Dotnetcom 运行于SAMESTA。Ok |
atlplugincom (Free) |
atlplugincom 运行于MTA。Ok |
atlplugincom (Apartmemt) |
Atlplugincom 运行于SAMESTA。ok |
|
Clientcom(Create From Other STA) |
Dotnetcom(Apartment) |
Dotnetcom 运行于SAMESTA。ok |
atlplugincom (Free) |
atlplugincom 运行于MTA。ok |
Atlplugincom (Apartmemt) |
Atlplugincom 运行于SAMESTA。ok |
|
Clientcom(Create From MTA) |
Dotnetcom(Apartment) |
Dotnetcom 运行于MainSTA。ok |
atlplugincom (Free) |
atlplugincom 运行于MTA。ok |
Atlplugincom (Apartmemt) |
Atlplugincom 运行于MainSTA。ok |
Case 3 : dotnet COM对象可以调用ATL COM对象非UI方,
模拟: dotnet COM 对象使用WWSDK COM Wrapper 对象的服务/方法.
前提: 由于aliim.exe 在进入后就call oleinitialize(NULL) 将自己带入了一个MAINSTA。因此测试中不再特别创建套间。
步骤:
1) 由于需要模拟一个合适的ATL COM wrapper ,因此在wwsdk.dll 初始化之后初始化 clientcom.dll.
2) Aliim.exe call clientcom.dll::Test。
3) Clientcom.dll::Test 调用Dotnetcom::OnNotify。
4) Dotnetcom.dll 在OnNotify处理中调用clientcom.dll::Service方法。
结论: (clientcom 始终在MAINSTA中)
|
Clientcom(MAINSTA) |
Dotnetcom(Apartment) |
Dotnetcom运行于SAMESTA。ok |
Dotnetcom (OtherSTA) |
Dotnetcom运行于OtherSTA。ok |
Dotnetcom (MTA) |
Dotnetcom 运行于MTA 。ok |
|
Clientcom(Create from OtherSTA) |
Dotnetcom(Apartment) |
Dotnetcom运行于SAMESTA。ok |
Dotnetcom (OtherSTA) |
Dotnetcom运行于OtherSTA。ok |
Dotnetcom (MTA) |
Dotnetcom 运行于MTA 。ok |
|
Clientcom(Create from MTA) |
Dotnetcom(Apartment) |
Dotnetcom运行于MainSTA。ok |
Dotnetcom (OtherSTA) |
Dotnetcom运行于OtherSTA。ok |
Dotnetcom (MTA) |
Dotnetcom 运行于MTA 。ok |
Case 4 : dotnet COM对象可以调用ATL COM对象UI方法
模拟: dotnet COM 对象使用WWSDK COM Wrapper 对象的服务/方法.
前提: 由于aliim.exe 在进入后就call oleinitialize(NULL) 将自己带入了一个MAINSTA。因此测试中不再特别创建套间。
步骤:
5) 由于需要模拟一个合适的ATL COM wrapper ,因此在wwsdk.dll 初始化之后初始化 clientcom.dll.
6) Aliim.exe call clientcom.dll::Test。
7) Clientcom::Test call dotnetcom::OnNotify。
8) Dotnetcom.dll 在OnNotify处理中调用clientcom.dll::Service方法。
结论: (clientcom 始终在MAINSTA中)
|
Clientcom(Create from MAINSTA) |
Dotnetcom(Apartment) |
Dotnetcom运行于MAINSTA。ok |
Dotnetcom (OtherSTA) |
Dotnetcom运行于OtherSTA。ok |
Dotnetcom (MTA) |
Dotnetcom 运行于MTA。ok |
|
Clientcom(Create from OtherSTA) |
Dotnetcom(Apartment) |
Dotnetcom运行于SAMESTA。ok |
Dotnetcom (OtherSTA) |
Dotnetcom运行于OtherSTA。ok |
Dotnetcom (MTA) |
Dotnetcom 运行于MTA。ok |
|
Clientcom(Create from MTA) |
Dotnetcom(Apartment) |
Dotnetcom运行于MAINSTA。ok |
Dotnetcom (OtherSTA) |
Dotnetcom运行于OtherSTA。ok |
Dotnetcom (MTA) |
Dotnetcom 运行于MTA。ok |
Case 4 : clientcom对象作为SDK发布给.Net用户(这儿主要检验了C#)是否方便可行?
方式 : tlbimp 工具生成 interop binary 将此bianary和com dll 一起发布,经过更换机器测试通过。
结论:
1. 采用ATL 开发的COM对象能够调用C# 开发.Net COM对象,反之也行。
2. 线程模型并不妨碍我们开发的MainSTA对象与.Net / ATLCOM 的交互,尽管会带来可能存在的性能影响(这个不在评估之列)。
3. WWSDK(COM版本)可以通过随阿里旺旺捆绑发布的方式打包 interop.dll+sdk.dll 发布,而作为开发者安装阿里旺旺后就可以在C#环境下通过导入reference方式访问我们的SDK。(这儿并没有评估.NetFramework 不同版本对我们发布的SDK是否有更多影响,本文测试了V2.0.50727)。
潜在风险说明
1. 测试中没有找到如何设置dotnetcom 的Apartment属性方式。因此测试MTA模式是通过atl对象来替代。 (风险低)
2. Wwsdk再发布给.Net plugin 开发者时候未评估不同版本.NetFramework对我们发布的interop对开发者的影响 .(风险中)
3. 未评估.Net 开发环境下除C#外的其他语言开发的组建同我们的wsdkcom交互。(风险中)
4. 采用类工厂单件模式能够避免实例反复创建,但是这个对象被用于不同套间时候存在问题,我们在编码的时候应该通过自定义单件模式解决(风险低)
尾声:
个人认为总体风险不高。
1. .Net plugin交互中还存在一些可以提高的一些细节目前未明了,而这些细节的解决,将有助于另我们的WWSDK对于.Net开发者来说更加专业。
2. 从可行性来说,个人认为在规定的范围内(确定的某个.NetFramework 版本上,确定的几种.Net 语言比如C# )可行。
3. 由于时间较短,覆盖的面也有所限制,不能就各种技术细节进行更加深入地预言。
Question:
1. interop 发布时候用的.Netframework如何和实际运行及其上的.Netframework版本不一致是否有问题?
2. 不同版本的interopdll存在于不同目录时候会否能够自动识别各自的interopdll.
3. 多个.Netframework/runtime version 运行于aliim.exe中会否有问题?(不属于本次技术预言范畴)
第二次修订
Case 1 : 不同版本的interopdll存在于不同目录时候会否能够自动识别各自的interopdll.
结论: 我们可以将interopxxx.dll 打包发布到 aliim.exe 目录下,那么所有.Net 开发的插件在被加载的时候将优先使用aliim.exe同目录下的而不会使用插件自己目录下的,因此我们可以建议插件开发者根本不用发布他们自己的interopxxx.dll。
Case 2 : 如果我们在某个版本发布了interopxxx.dll 比如它内部实际上包装了COM的一个对象一个方法. 然后过了一段时间我们发布了WWSDKCOM.dll 在某个对象上增加了一些方法,然后又增加了一个对象,同时更新发布了interopxx.dll 那么对于那些曾经使用老的interopxxx.dll 的插件能否兼容?
结论: ok.
Case 3: 如果我们仅仅通过一个CLSID以及一个.Net COM dll 我们在发布或者安装或者加载插件前如何确保这个.Net被正确注册? 然后可创建!
结论: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe complugin_1.dll /codebase , 将用于将.Net COM component 注册到注册表中,此后VC 客户端就可以通过registry 创建COM组件了. 在这个过程中实际上建议.Net 开发者提供StrongName 的.Net COM.
Case 4 : 随我们的阿里旺旺安装程序而提供的interop.wwsdk.dll 如果是用某个版本的.dotnetframe 工具生成的,那么对于.Net 开发者开发时候使用的不同.Netframework 版本有否影响? 对于最终运行时候会否有影响?
结论: 我采用了V1.1 SDK 带有tlbimp 生成interop.xxx.dll 在只有V2 .Netframework 的机器上运行没有问题.