-
Notifications
You must be signed in to change notification settings - Fork 7
/
ComActivationHelpers.cs
98 lines (79 loc) · 4.14 KB
/
ComActivationHelpers.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace SharpGen.Runtime
{
public static class ComActivationHelpers
{
private const uint RPC_E_CHANGED_MODE = 0x80010106;
private const uint COINIT_MULTITHREADED = 0x0;
private const uint COINIT_APARTMENTTHREADED = 0x2;
public static void CoInitialize()
{
if (CoInitializeEx(IntPtr.Zero, COINIT_APARTMENTTHREADED) == RPC_E_CHANGED_MODE)
CoInitializeEx(IntPtr.Zero, COINIT_MULTITHREADED);
}
public static Result CreateComInstance(Guid classGuid, ComContext context, Guid interfaceGuid,
out IntPtr comObject)
{
return PlatformDetection.IsAppContainerProcess
? CreateComInstanceRestricted(classGuid, context, interfaceGuid, out comObject)
: CreateComInstanceUnrestricted(classGuid, context, interfaceGuid, out comObject);
}
#region Win32
public static Result CreateComInstanceUnrestricted(Guid classGuid, ComContext context, Guid interfaceGuid,
out IntPtr comObject) =>
CoCreateInstance(classGuid, IntPtr.Zero, context, interfaceGuid, out comObject);
[DllImport("ole32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
private static extern uint CoInitializeEx([In] [Optional] IntPtr pvReserved, [In] uint dwCoInit);
[DllImport("ole32.dll", ExactSpelling = true,
EntryPoint = "CoCreateInstance", PreserveSig = true)]
private static extern Result CoCreateInstance([In] [MarshalAs(UnmanagedType.LPStruct)]
Guid rclsid,
IntPtr pUnkOuter,
ComContext dwClsContext,
[In] [MarshalAs(UnmanagedType.LPStruct)]
Guid riid,
out IntPtr comObject);
#endregion
#region UWP
public static unsafe Result CreateComInstanceRestricted(Guid classGuid, ComContext context, Guid interfaceGuid,
out IntPtr comObject)
{
var localQuery = new MultiQueryInterface
{
InterfaceIID = new IntPtr(&interfaceGuid),
IUnknownPointer = IntPtr.Zero,
ResultCode = 0
};
var result = CoCreateInstanceFromApp(classGuid, IntPtr.Zero, context, IntPtr.Zero, 1, ref localQuery);
comObject = localQuery.IUnknownPointer;
if (!result.Success)
return result;
if (!localQuery.ResultCode.Success)
return localQuery.ResultCode;
if (result != Result.Ok)
return result;
if (localQuery.ResultCode != Result.Ok)
return localQuery.ResultCode;
return Result.Ok;
}
[DllImport("api-ms-win-core-com-l1-1-0.dll", ExactSpelling = true,
EntryPoint = "CoCreateInstanceFromApp", PreserveSig = true)]
private static extern Result CoCreateInstanceFromApp([In] [MarshalAs(UnmanagedType.LPStruct)]
Guid rclsid,
IntPtr pUnkOuter,
ComContext dwClsContext,
IntPtr reserved,
int countMultiQuery,
ref MultiQueryInterface query);
[StructLayout(LayoutKind.Sequential)]
private struct MultiQueryInterface
{
public IntPtr InterfaceIID;
public IntPtr IUnknownPointer;
public Result ResultCode;
}
#endregion
}
}