vb.net 通过类厂创建com对象的方法

来源:互联网 发布:java入门到精通txt 编辑:程序博客网 时间:2024/04/28 19:06

    vb.net中要创立com对象可以用new或者CreateObject,就像C++中的CoCreateInstance,一步调用就直接创建了com对象。在它们之中包括了对CoGetClassObject和CreateInstance的调用。默认使用的类厂是IClassFactory。 
    一般情况下,new或CreateObject已经够用了。但是如果我们的com组件增加了授权,也就是使用了IClassFactory2接口。那么在vb中继续用这种方法就不能创建我们所需要的组件了。我们必须使用IClassFactory2。
    在C++中实现很简单。只需要通过CoGetClassObject获得IClassFactory2接口,然后调用它的CreateInstanceLic来创建组件。
    因此,在vb.net中,我们就可以仿照c++中的方法。下面是相关代码:
    首先声明IClassFactory2的接口。IClassFactory2.idl如下:

[
    uuid(6ED6AF97
-F279-4d57-A392-0B8ACF89426C),
    version(
1.0),
    helpstring(
"INVENTOROCIDL Type Library 1.0")
]
library INVENTOROCIDL
{
    
interface IClassFactory2;

    typedef 
enum enuCLSCTX
    
{
        enuCLSCTX_INPROC_SERVER    
= 1,
        enuCLSCTX_INPROC_HANDLER   
= 2,
        enuCLSCTX_LOCAL_SERVER     
= 4,
        enuCLSCTX_REMOTE_SERVER    
= 16,
        enuCLSCTX_NO_CODE_DOWNLOAD 
= 400,
        enuCLSCTX_NO_FAILURE_LOG 
= 4000,
        enuCLSCTX_SERVER    
= (1 | 4 | 16),
        enuCLSCTX_ALL       
= (2 | 1)
    }
 CLSCTX;

    [
        
object,
        uuid(B196B28F
-BAB4-101A-B69C-00AA00341D07),
        pointer_default(unique)
    ]

    
interface IClassFactory2 : IClassFactory
    
{
        typedef IClassFactory2 
* LPCLASSFACTORY2;

        typedef 
struct tagLICINFO {
            LONG cbLicInfo;
            BOOL fRuntimeKeyAvail;
            BOOL fLicVerified;
        }
 LICINFO;

        typedef 
struct tagLICINFO * LPLICINFO;

        HRESULT GetLicInfo(
            [
out, retval] LICINFO * pLicInfo
            );

        HRESULT RequestLicKey(
            [
in] LONG dwReserved,
            [
out, retval] BSTR * pBstrKey
            );

        [local]
        HRESULT CreateInstanceLic(
            [
in] IUnknown * pUnkOuter,
            [
in] IUnknown * pUnkReserved,
            [
in] GUID* riid,
            [
in] BSTR bstrKey,
            [
out, retval, iid_is(riid)] PVOID * ppvObj
            );

    }

}

用midl编译成IClassFactory2.tlb,并导入到vb.net的工程当中。
声明如下api用于得到IClassFactory2接口:
    Declare Function CoGetClassObject Lib "ole32.dll" (ByRef rclsid As Guid, ByVal context As Short, ByRef serverInfo As IntPtr, ByRef riid As Guid, ByRef ppv As IntPtr) As Integer
添加如下代码:

Const bstrInventorApplication As String = "{B6B5DC40-96E3-11d2-B774-0060B0F159EF}"
    
Const bstrIClassFactory2 As String = "{B196B28F-BAB4-101A-B69C-00AA00341D07}"
    
Const bstrIDispatch As String = "{00020400-0000-0000-C000-000000000046}"

    
Private IClsFry2 As INVENTOROCIDL.IClassFactory2 
    
Dim bstrLicence As String = "12345678"   'licence key
    Dim guidInventorApplication As Guid = New Guid(bstrInventorApplication)
    
Dim guidIClassFactory2 As Guid = New Guid(bstrIClassFactory2)
    
Dim guidIDispatch As Guid = New Guid(bstrIDispatch)
    
Dim InventorGuid As INVENTOROCIDL.GUID  'used by CreateInstanceLic,defined in INVENTOROCIDL

     
'transform Guid of IDispatch to INVENTOROCIDL.GUID
      Dim byteArry() As Byte = guidIDispatch.ToByteArray()
      
Dim MyGC As GCHandle = GCHandle.Alloc(byteArry, GCHandleType.Pinned)
      InventorGuid 
= CType(Marshal.PtrToStructure(MyGC.AddrOfPinnedObject, InventorGuid.GetType()), INVENTOROCIDL.GUID)

      
'get the IClassFactory2 Interface
      Dim obj As IntPtr
      CoGetClassObject(guidInventorApplication, 
CInt(INVENTOROCIDL.enuCLSCTX.enuCLSCTX_LOCAL_SERVER), Nothing, guidIClassFactory2, obj)
       IClsFry2 
= CType(Marshal.GetTypedObjectForIUnknown(obj, System.Type.GetTypeFromCLSID(guidIClassFactory2)), INVENTOROCIDL.IClassFactory2)

        
'create Inventor Instance by using Licence
       obj = IClsFry2.CreateInstanceLic(NothingNothing, InventorGuid, bstrLicence)
        InvApp 
= CType(Marshal.GetTypedObjectForIUnknown(obj, System.Type.GetTypeFromCLSID(guidInventorApplication)), Inventor.Application)

致此创建成功!

 

 

原创粉丝点击