我尝试创建一个使用COM接口消耗插件的程序。
我实现了IClassFactory接口来创建插件实例。 CreateInstance-Method以这种方式实现:
(table1 JOIN table2) UNION (table1 JOIN table3)
public int CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject)
{
MessageBox.Show("TestClassFactory CreateInstance");
ppvObject = IntPtr.Zero;
if (pUnkOuter != IntPtr.Zero)
{
// The pUnkOuter parameter was non-NULL and the object does
// not support aggregation.
Marshal.ThrowExceptionForHR(ComNative.CLASS_E_NOAGGREGATION);
}
if (riid == new Guid(ManagerGuids.ClassId)
|| riid == new Guid(ComNative.IID_IDispatch)
|| riid == new Guid(ComNative.IID_IUnknown))
{
MessageBox.Show("Pre GetComInterfaceForObject");
// Create the instance of the .NET object
// The container has to be passed as property and not by constructor injection.
// This is because COM (de-)registration needs a constructor without parameters.
ppvObject = Marshal.GetComInterfaceForObject(new NetPlugin(), typeof(INetPlugin));
MessageBox.Show("Post GetComInterfaceForObject");
}
else
{
// The object that ppvObject points to does not support the
// interface identified by riid.
Marshal.ThrowExceptionForHR(ComNative.E_NOINTERFACE);
}
return WinError.S_OK;
}
的调用返回无效参数错误(E_INVALIDARG)。
方法的论点:
NetPlugin:
Marshal.GetComInterfaceForObject(new NetPlugin(), typeof(INetPlugin));
INetPlugin:
[ClassInterface(ClassInterfaceType.None)]
[Guid(ManagerGuids.ClassId)]
[ComVisible(true)]
public class NetPlugin : INetPlugin
{
public NetPlugin()
{
}
[ComVisible(true)]
[DispIdAttribute(0x1)]
public String LastParameters
{
get { return ""; }
set { }
}
[ComVisible(true)]
[DispIdAttribute(0x2)]
public String Vendor
{
get { return "Company"; }
set { }
}
[ComVisible(true)]
[DispIdAttribute(0x3)]
public String Description
{
get { return "Test plugin written in .NET"; }
set { }
}
[ComVisible(true)]
[DispIdAttribute(0x4)]
public String Version
{
get { return "1.0"; }
set { }
}
[ComVisible(true)]
[DispIdAttribute(0x5)]
public String Category
{
get { return "Void"; }
set { }
}
[ComVisible(true)]
[DispIdAttribute(0x6)]
public String MenuEntry
{
get { return "NetPlugin"; }
set { }
}
[ComVisible(true)]
[DispIdAttribute(0x7)]
public String MessageString
{
get { return "NetPlugin"; }
set { }
}
[ComVisible(true)]
[DispIdAttribute(0x8)]
public String TooltipText
{
get { return "Tooltip NetPlugin"; }
set { }
}
[ComVisible(true)]
[DispIdAttribute(0x9)]
public String FriendlyName
{
get { return "NetPlugin FFFFF Friendly"; }
set { }
}
[ComVisible(true)]
[DispIdAttribute(0xa)]
public String BitmapResourceSmall
{
get { return "BitmapResourceSmall.bmp"; }
set { }
}
[ComVisible(true)]
[DispIdAttribute(0xb)]
public String BitmapResourceLarge
{
get { return "BitmapResourceLarge.bmp"; }
set { }
}
[ComVisible(true)]
[DispIdAttribute(0xc)]
public String Key
{
get { return ""; } // must be empty
set { }
}
[ComVisible(true)]
[DispIdAttribute(0xd)]
public String Reserved
{
get { return "Void"; }
set { }
}
[ComVisible(true)]
[DispIdAttribute(0xe)]
public Int32 Run()
{
//-- Return scode
return 0;
}
}
NetPlugin以这种方式注册:
[Guid(ManagerGuids.InterfaceId), ComVisible(true)]
interface INetPlugin
{
[DispId(0x1)]
String LastParameters { get; set; }
[DispId(0x2)]
String Vendor { get; set; }
[DispId(0x3)]
String Description {get; set; }
[DispId(0x4)]
String Version { get; set; }
[DispId(0x5)]
String Category { get; set; }
[DispId(0x6)]
String MenuEntry { get; set; }
[DispId(0x7)]
String MessageString { get; set; }
[DispId(0x8)]
String TooltipText { get; set; }
[DispId(0x9)]
String FriendlyName { get; set; }
[DispId(0xa)]
String BitmapResourceSmall { get; set; }
[DispId(0xb)]
String BitmapResourceLarge { get; set; }
[DispId(0xc)]
String Key { get; set; }
[DispId(0xd)]
String Reserved { get; set; }
[DispId(0xe)]
Int32 Run();
}
INetPlugin以这种方式注册:
RegistrationServices rs = new RegistrationServices();
bool b = rs.RegisterAssembly(System.Reflection.Assembly.GetExecutingAssembly(), AssemblyRegistrationFlags.SetCodeBase);
if (!b)
return 998;
String exePath = new Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath;
Registry.SetValue(@"HKEY_CLASSES_ROOT\CLSID\{" + ManagerGuids.ClassId + @"}\LocalServer32", "", exePath);
我会非常感谢任何帮助!