A sample demonstrates both in-process and out-of-process WinRT server with C# + CsWinRT.
The Windows Runtime (WinRT) supports the concept of In Process Servers, which allows for using objects that are in a different dlls with super-fast performance and easy-to-use ABI.
The Windows Runtime (WinRT) supports the concept of Out Of Process (OOP) Servers, which allows for using objects that are in a different process (or even a different machine) as though they were in the local process.
It uses WinRT for communication so that any language that can use WinRT is able to be a WinRT server or serve as a client of a WinRT server.
With built-in support for async primitives such as IAsyncAction
, IAsyncOperation<T>
and etc., it is easy to work with async code.
Most RPC/ICP systems are just sending messages between the two processes. At most they can serialize and deserialize an object.
WinRT allows for more complicated objects, where the returned types can have methods, events, and properties. If you could do it with a local object, you can do it with a remote object.
The server project needs to provide the implementation of types, and it uses CsWinRT to automatically generate interop code and winmd file, where the winmd file is served as a contract to be used between server and clients.
Structs, classes and delegates are supported, to add a type in the WinRT server:
- If you are adding a class, it must be sealed, and make sure you also add the type as an
ActivatableClass
inPackage.appxmanifest
underOutOfProcessServer
(orInProcessServer
if you are using the in-proc server), and if you are using the out-of-proc WinRT server, you also need to register an activation factory for it in theRoRegisterActivationFactories
call. - Methods, properties and events for both static and non-static are supported, but the type must have a projection (primitive types, types that have a .NET/WinRT mapping, WinRT types and types defined in the server project) before it can be used in the signature.
The client project only needs to consume the winmd file generated by the server project, all the server activation, type instantiation and marshaling things will be automatically done by CsWinRT.
To switch the out-of-process WinRT server to in-process WinRT server:
- Change the OutputType of the server project to
Library
. - Open Package.appxmanifest, uncomment the in-process server manifest, and comment the out-of-process server manifest
Current the DesktopBridge project system (i.e. wapproj) has two issues need to workaround.
- The winmd needs to be removed from
_AppxWinmdFilesToHarvest
, see the targetRemoveWinMDRefForManifestAutoGen
in the wapproj. Otherwise an incorrectinProcessServer
entry will be added to the manifest which will cause the build to fail. - The server project also needs to include the winmd file in the
ItemGroup
, otherwise the server implementation (i.e.WinRTServer.dll
in this demo) will be removed from the package layout if you publish it to appx package, which can lead to failure while starting the server. This is because in the in-process server case, the server implementation should be placed next to the client as it will be loaded into the client process, however, it's not the case for out-of-process. Here the toolchain again assumes we are using an in-process server and does this unnecessary thing for us.