在STA线程中使用多线程COM对象

时间:2013-06-05 10:02:54

标签: c# com

我正在尝试在.net应用程序中使用第三方com对象。

通过这个com对象,我试图连接到mssql数据库。

com对象仅适用于MTA线程。 注册表中对象的“ThreadingModel”值为“Apartment”。

当我尝试在控制台应用程序中使用对象时 - 连接成功。 当我将项目类型更改为Windows应用程序时 - 连接失败(com对象方法返回消息“-2147023550:发生OLE DB错误。代码80070542h”)。 当我将STAThread属性添加到控制台应用程序的Main方法时 - 连接失败。

我试图从另一个带有MTA公寓的线程调用我的com对象,但连接也失败了。

我正在尝试通过以下代码创建我的com对象:

var result = ComSecurity.CoInitializeSecurity(
                IntPtr.Zero,
                -1,
                IntPtr.Zero,
                IntPtr.Zero,
                RpcAuthnLevel.None,
                RpcImpLevel.Impersonate,
                IntPtr.Zero,
                EoAuthnCap.None,
                IntPtr.Zero);

var serverApplication = Activator.CreateInstance(Type.GetTypeFromProgID("LoodsmanServerApplication.MainSystem")) as IMainSystem;

...

public enum RpcAuthnLevel
    {
        Default = 0,
        None = 1,
        Connect = 2,
        Call = 3,
        Pkt = 4,
        PktIntegrity = 5,
        PktPrivacy = 6
    }

public enum RpcImpLevel
    {
        Default = 0,
        Anonymous = 1,
        Identify = 2,
        Impersonate = 3,
        Delegate = 4
    }

    public enum EoAuthnCap
    {
        None = 0x00,
        MutualAuth = 0x01,
        StaticCloaking = 0x20,
        DynamicCloaking = 0x40,
        AnyAuthority = 0x80,
        MakeFullSIC = 0x100,
        Default = 0x800,
        SecureRefs = 0x02,
        AccessControl = 0x04,
        AppID = 0x08,
        Dynamic = 0x10,
        RequireFullSIC = 0x200,
        AutoImpersonate = 0x400,
        NoCustomMarshal = 0x2000,
        DisableAAA = 0x1000
    }

[DllImport("ole32.dll")]
public static extern int CoInitializeSecurity(IntPtr pVoid, int
            cAuthSvc, IntPtr asAuthSvc, IntPtr pReserved1, RpcAuthnLevel level,
            RpcImpLevel impers, IntPtr pAuthList, EoAuthnCap dwCapabilities, IntPtr
            pReserved3);

有没有办法从STA线程使用MTA COM对象?

1 个答案:

答案 0 :(得分:0)

您应该使用委派级别而不是模拟。 MTA / STA与它无关。

var result = ComSecurity.CoInitializeSecurity(
                IntPtr.Zero,
                -1,
                IntPtr.Zero,
                IntPtr.Zero,
                RpcAuthnLevel.None,
                RpcImpLevel.Delegate,
                IntPtr.Zero,
                EoAuthnCap.None,
                IntPtr.Zero);