My Blog

Caricare oggetti COM non registrati

by lupok on martedì 16 settembre 2014 16:03

Ho creato un semplice oggetto COM con il seguente IDL:

// ComObject.idl : IDL source for ComObject
//
 
// This file will be processed by the MIDL tool to
// produce the type library (ComObject.tlb) and marshalling code.
 
import "oaidl.idl";
import "ocidl.idl";
 
[
	object,
	uuid(1C0C9AB2-4388-4E1A-A897-D63DD16910AC),
	dual,
	nonextensible,
	pointer_default(unique)
]
interface IComClass : IDispatch{
   [id(1)] HRESULT CalculateArea(FLOAT a, FLOAT b, [out] FLOAT* area);
};
[
	uuid(F687E8E6-C714-404B-B946-57DFD49D1D1A),
	version(1.0),
]
library ComObjectLib
{
	importlib("stdole2.tlb");
	[
		uuid(916BBACF-990F-44DC-80B2-AD2FF5368E57)		
	]
	coclass ComClass
	{
		[defaultinterface IComClass;
	};
};
 

 

A questo punto per creare una istanza di IComClass ed invocare il metodo CalculateArea:

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
 
namespace LoadingUnregisteredCOMObjectsWithDotNET
{
   class Program
   {
      static Guid IID_IUNKNOWN = new Guid("00000000-0000-0000-C000-000000000046");
      static Guid IID_COMCLASS = new Guid("916BBACF-990F-44DC-80B2-AD2FF5368E57");
      static Guid IID_CLASSFACTORY = new Guid("00000001-0000-0000-c000-000000000046");
      static Guid IID_IUNKNOW = new Guid("00000000-0000-0000-C000-000000000046");
 
      [DllImport("kernel32", EntryPoint = "LoadLibrary", SetLastError = true, CharSet = CharSet.Unicode)]
      static extern IntPtr LoadLibrary(string lpFileName);
 
      [DllImport("kernel32")]
      public static extern bool FreeLibrary(IntPtr hModule);
 
      [DllImport("kernel32", EntryPoint = "GetProcAddress", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
      static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
 
      delegate int DllGetClassObject(ref Guid clsid, ref Guid iid, [OutMarshalAs(UnmanagedType.Interface)] out IClassFactory classFactory);
 
      [Guid("00000001-0000-0000-c000-000000000046")]
      [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
      [ComImport]
      internal interface IClassFactory
      {
         void CreateInstance([MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter, ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppvObject);
         void LockServer(bool fLock);
      }
 
      [System.Runtime.InteropServices.ComImport]
      [System.Runtime.InteropServices.Guid("1C0C9AB2-4388-4E1A-A897-D63DD16910AC")]
      public interface IComClass
      {
         [System.Runtime.InteropServices.DispId(1)]
         void CalculateArea(float a, float b, ref float area);
      }
 
      static void Main(string[] args)
      {
         IntPtr library = IntPtr.Zero;
         library = LoadLibrary("ComObject.dll");
 
         IntPtr ptr = GetProcAddress(library, "DllGetClassObject");
 
         var dllGetClassObjectCallback = (DllGetClassObject)Marshal.GetDelegateForFunctionPointer(ptr, typeof(DllGetClassObject));
 
         IClassFactory classFactory;
 
         var hresult = dllGetClassObjectCallback(ref IID_COMCLASS, ref IID_CLASSFACTORY, out classFactory);
 
         Object ppvObject;
         classFactory.CreateInstance(nullref IID_IUNKNOW, out ppvObject);
 
         IComClass comClass = (IComClass)ppvObject;
 
         float area = 0f;
         comClass.CalculateArea(34f, 67f, ref area);
 
         FreeLibrary(library);
      }
   }
}

 

LoadingUnregisteredCOMObjectsWithDotNET.zip
ComObject.zip

Blogs Parent Separator My Blog
Author
lupok

My Blog

Tags