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( Nothing , Nothing , InventorGuid, bstrLicence)
InvApp = CType (Marshal.GetTypedObjectForIUnknown(obj, System.Type.GetTypeFromCLSID(guidInventorApplication)), Inventor.Application)
致此创建成功!
版权声明:本文为quailzhang原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。