我正在为第三方系统实现.NET COM服务器,即COM客户端(C ++)。我提供了IDL,我曾经用tlbimp生成.dll。在API中,它还建议实现双和接口接口。在这个COM服务器中,我必须实例化一个WPF组件,该组件当前失败,因为它必须从STA线程调用。我已经做了很多关于如何强制我的COM服务器成为线程模型公寓的googeling。我更改了没有帮助的注册表项,然后我在stackoverflow上发现了以下文章:How to make make a .NET COM object apartment-threaded?
我按照说明实现了ICustomQueryInterface,但它失败了;在这里我的IDL:
[
object,
uuid(ABB09FED-F7BE-4654-88BC-5F4D2941111A),
dual,
nonextensible,
helpstring("IDVRServer Interface"),
pointer_default(unique)
]
interface IDVRServer : IDispatch{
[id(1), helpstring("Creates a DVR Unit Connection based on connection information
such as IP address, user name...")]
HRESULT CreateConnection(
[in] DVRConnectionInfo* pConnInfo, [out, retval] IDVRUnitConnection** ppConn);
};
这里是C#中的实现(包括ICustomQueryInterface):
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)
public class DVRServer : IDVRServer, ICustomQueryInterface
{
private IntPtr _dvrPointer;
public DVRServer() {
NativeMethods.CoGetStdMarshalEx(this, NativeMethods.SMEXF_SERVER, out _dvrPointer);
}
public CustomQueryInterfaceResult GetInterface(ref Guid iid, out IntPtr ppv) {
if (iid == NativeMethods.IID_IMarshal_DVRServerDispatch)
{
res = 0;
res = Marshal.QueryInterface(_dvrPointer, ref NativeMethods.IID_IMarshal_DVRServerDispatch, out ppv);
string hex = res.ToString("X");
if (res != 0)
{
return CustomQueryInterfaceResult.Failed;
}
return CustomQueryInterfaceResult.Handled;
}
return CustomQueryInterfaceResult.Failed;
}
static class NativeMethods
{
public static Guid IID_IMarshal_DVRServerDispatch = new Guid("ABB09FED-F7BE-4654-88BC-5F4D2941111A");
public const UInt32 SMEXF_SERVER = 1;
[DllImport("ole32.dll", PreserveSig = true)]
public static extern void CoGetStdMarshalEx([MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter, UInt32 smexflags, out IntPtr ppUnkInner);
}
Marshal.QueryInterface的结果始终为0x80004002 E_NOINTERFACE。我已经尝试了很多不同的东西,也来自StandardOleMarshalObject和ServicedComponent,但没有任何效果。还有一个问题是,如果注册表完全可以计算,或者我可以忽略那里的ThreadingModel,我从Noseratio的帖子中得不到。提前感谢您对该主题的任何帮助。
我使用VisualStudio 2012和.Net Framework 4。