using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Threading.Tasks;
namespace WinRTServer
{
[ComVisible(true)]
[Guid("782674D9-5CBB-4FCA-AD72-D9AC5F7AE963")]
[InterfaceType(ComInterfaceType.InterfaceIsIInspectable)]
public interface IPresenceWriter
{
[PreserveSig]
int TestMethod(
long p0,
int p1,
[MarshalAs(UnmanagedType.HString)] string p2,
int p3);
}
[ComVisible(true)]
[Guid("4abc30bc-1584-4075-8fef-89348af82419")]
public class TestIActivationFactory : IActivationFactory
{
public TestIActivationFactory()
{
}
public int ActivateInstance(out object instance)
{
instance = new TestComVisibleClass();
Console.WriteLine("ActivateInstance:=>" + instance);
return 0;
}
}
[ComVisible(true)]
[Guid("4abc30bc-1584-4075-8fef-89348af82419")]
public class TestComVisibleClass : IPresenceWriter
{
public int TestMethod(long p0, int p1, string p2, int p3)
{
Console.WriteLine("TestMethod:=>" + p2);
return 0;
}
}
public static class WinRTHelper
{
// public static string gcls = "WinRTServer.TestCalculator";
public static string gcls = "Windows.Gaming.GameBar.PresenceServer.Internal.PresenceWriter";
public delegate int DllGetActivationFactoryDelegate(
[MarshalAs(UnmanagedType.HString)] string activatableClassId, out IActivationFactory factory);
public static int DllGetActivationFactory([MarshalAs(UnmanagedType.HString)] string activatableClassId, out IActivationFactory factory)
{
try
{
Console.WriteLine("DllGetActivationFactory:=>" + activatableClassId);
if (activatableClassId == gcls)
{
factory = new TestIActivationFactory();
return 0;
}
throw new NotImplementedException();
}
finally
{
}
}
}
[ComImport]
[Guid("00000035-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIInspectable)]
public interface IActivationFactory
{
[PreserveSig]
int ActivateInstance([MarshalAs(UnmanagedType.IInspectable)] out object instance);
}
class Program
{
[DllImport("ComBase.dll", PreserveSig = false)]
private static extern int RoRegisterActivationFactories(
IntPtr[] activatableClassIds,
IntPtr[] activationFactoryCallbacks, int count,
out int cookie);
[DllImport("ComBase.dll", PreserveSig = false)]
private static extern int RoRevokeActivationFactories(int cookie);
static void Main(string[] args)
{
// 1. 必须初始化当前线程的 Windows 运行时
// 对于进程外服务,通常使用多线程单元(RO_INIT_MULTITHREADED)。
// P/Invoke 声明可参考文档或使用 Windows.Win32 中的 API。
// 此处省略其定义。
// 假设我们已经通过 `RoInitialize` 正确初始化了当前线程的 Windows 运行时。
// 准备要注册的类名(即命名空间.类名)
string[] classNames = new string[] { WinRTHelper.gcls };
IntPtr[] hstrings = new IntPtr[classNames.Length];
for (int i = 0; i < classNames.Length; i++)
{
hstrings[i] = WindowsRuntimeMarshal.StringToHString(classNames[i]);
}
// 获取 InternalModule.GetActivationFactory 函数指针
// 注意:这需要从 CsWinRT 生成的 InternalModule 类中获取委托并转换为函数指针。
// 为确保演示清晰,此处简化为获取其函数指针的逻辑。
IntPtr[] factoryCallbacks = new IntPtr[] { Marshal.GetFunctionPointerForDelegate<WinRTHelper.DllGetActivationFactoryDelegate>(WinRTHelper.DllGetActivationFactory) };
// 注册激活工厂,得到 cookie
int ret = RoRegisterActivationFactories(hstrings, factoryCallbacks, 1, out int cookie);
Console.WriteLine("RoRegisterActivationFactories:=>" + ret.ToString("x"));
if (ret != 0)
{
Marshal.ThrowExceptionForHR(ret);
}
Console.ReadKey();
// 退出前取消注册
ret = RoRevokeActivationFactories(cookie);
Console.WriteLine("RoRevokeActivationFactories:=>" + ret.ToString("x"));
if (ret != 0)
{
Marshal.ThrowExceptionForHR(ret);
}
// 最后别忘了调用 RoUninitialize 清理
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace WinRTClient
{
[ComVisible(true)]
[Guid("782674D9-5CBB-4FCA-AD72-D9AC5F7AE963")]
[InterfaceType(ComInterfaceType.InterfaceIsIInspectable)]
public interface IPresenceWriter
{
[PreserveSig]
int TestMethod(
long p0,
int p1,
[MarshalAs(UnmanagedType.HString)] string p2,
int p3);
}
class Program
{
// public static string gcls = "WinRTServer.TestCalculator";
public static string gcls = "Windows.Gaming.GameBar.PresenceServer.Internal.PresenceWriter";
[DllImport("combase.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
[return: MarshalAs(UnmanagedType.IInspectable)]
public static extern object RoActivateInstance([MarshalAs(UnmanagedType.HString)] string activatableClassId);
static void Main(string[] args)
{
object act = RoActivateInstance(gcls);
Console.WriteLine(act);
IPresenceWriter obj = act as IPresenceWriter;
Console.WriteLine(obj);
int ret= obj.TestMethod(1, 0, "fake", 2);
Console.WriteLine("TestMethod:=>" +ret);
}
}
}