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

    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)

致此创建成功!

 

 

你可能感兴趣的:(C++/vc,vb.net,interface,server,string,c++,struct)