WinRT Extensions using RuntimeBroker

Have you ever wanted to do something naughty from your lovely well behaved sandboxed WinRT application?  Do you need to call some Win32 API that you don’t have permission to do from WinRT?

Well WinRT itself does this using a separate service called the RuntimeBroker.  Many WinRT objects use RPC to call into this broker process and do those things that need elevated priviledges.

I built a sample application that shows how to do this.  Essentially it goes something like this:

  1. Create a static C++ library containing a MIDL interface and compile it using /winrt to make it a windows runtime (WinRT) interface. 
  2. This generates RPC proxy stuff needed to marshal the interface across processes.  Compile this into a new C++ DLL called “YourInterface.ProxyStub.dll”.  You will register this dll using regsvr32 and this is needed for RPC to work.  This proxy stub and the implementing broker dll will need to live in a location your WinRT app can access, like c:\windows\system32.
  3. Next create a Universal C++ DLL called “YourInterfaceBroker.dll” – this will contain the implementation of the interface and is designed to run in the RuntimeBroker process.  This DLL will be able to call out to Win32 and do interesting things.
  4. Register the broker using a custom registry script.
  5. Lastly create a C# Blank Universal WinRT application to test out your new interface, referencing the *.winmd that was generated by step 1.  When you instantiate your new runtime class it is loaded into the RuntimeBroker process, and your C# app gets back the client proxy to it so each call to that object is marshalled automatically to the RuntimeBroker. 

See the sample code:

MIDL Interface Library

In my sample I started with this static C++ library, I added a MIDL file called Microsoft.Service.Sample.idl, this defines the name of the *.winmd so its namespace has to match the filename.  I then used the MIDL Tab in the C++ properties to turn on “Enable Windows Runtime” /winrt compile option.  The *.winmd file is placed in the project output directory. I built it once and this also generates a dlldata.c and *_i.c and *_p.c files.  I added those files to the project.  To compile them it is easier if you just turn off the C++ option for precompiled headers.  I also added the C++ preprocessor defines: WIN32;_WINDOWS;.  So now you have a static library containing the RPC stubs needed later.  For the purposes of this sample app I defined the following simple WinRT interface and runtime class:


#ifndef NTDDI_WIN8
#define NTDDI_WIN8                          0x06020000

namespace Microsoft
    namespace Service
        namespace Sample
            interface IMyService : IInspectable
                HRESULT DoSomethingFun();

            runtimeclass MyService
                [default] interface IMyService;



I then added a C++ Win32 DLL project called MyService.ProxyStub.  This dll has to include the above files again, but this time with the C++ preprocessor definition “REGISTER_PROXY_DLL”, and you need to generate a new GUID for your runtime class id (different from the one in the MIDL file) in a new ProxyEntry.c file as follows:

// {62C41977-4CCC-4D4E-9C8C-A842DB7182E6}

#definePROXY_CLSID_IS { 0x62c41977, 0x4ccc, 0x4d4e,{ 0x9c, 0x8c, 0xa8, 0x42, 0xdb, 0x71, 0x82, 0xe6 } };











This is also easier to compile if you turn off precompiled headers.  You also need to add a Modile Definition file for the DLL containing:

DllGetClassObject           PRIVATE
DllCanUnloadNow             PRIVATE
DllRegisterServer           PRIVATE
DllUnregisterServer         PRIVATE

You’ll also need to add a VC++ Include Directory pointing at your interface static lib directory where the dlldata.c and *_i.c and *_p.c files got generated.  You will also need to add the linker input “rpcrt4.lib”.  This generates the proxy stub needed for RPC to work.  This dll will be registered using regsvr32.


Next I added a Universal C++ DLL project called “MyServiceBroker”.  I added a reference to the static library project, I included #include<ObjIdl.h>in the pch.h file and again added the VC++ include directory where the *_h.h file was generated.  I wanted this DLL to work on the IoT SKU of Windows 10, which is why I used Universal DLL, but I want to run this outside an app container so I removed the following from the *.vcxproj file: <AppContainerApplication>true</AppContainerApplication>.  I also added the following linker instructions to each <Link> section:
    <IgnoreSpecificDefaultLibraries>comsuppwd.lib; comsuppw.lib; kernel32.lib; ole32.lib; user32.lib</IgnoreSpecificDefaultLibraries>
AdditionalDependencies>Wlanapi.lib;mincore.lib;onecoreuap.lib; WindowsApp.lib;</AdditionalDependencies>

Lastly I added the a class that implements my new interface as follows:


namespace Microsoft
namespace Service
namespace Sample
classCMyService : public Microsoft::WRL::RuntimeClass<ABI::Microsoft::Service::Sample::IMyService, Microsoft::WRL::FtmBase>
InspectableClass(RuntimeClass_Microsoft_Service_Sample_MyService, PartialTrust);



constCMyService& operator = (constCMyService&);


Then I added an empty implementation the the .cpp file.  I also replaced the contents of the dllmain.cpp file with the following:


using namespace Microsoft::WRL;

STDAPI DllGetActivationFactory(_In_HSTRINGactivatableClassId, _COM_Outptr_IActivationFactory **factory)
return Module<ModuleType::InProcDisableCaching>::GetModule().GetActivationFactory(activatableClassId, factory);

DllGetClassObject(_In_REFCLSIDrclsid, _In_REFIIDriid, _Outptr_LPVOIDFAR* ppv)
return Module<ModuleType::InProcDisableCaching>::GetModule().GetClassObject(rclsid, riid, ppv);

STDAPI DllCanUnloadNow()
if (Module<ModuleType::InProcDisableCaching>::GetModule().GetObjectCount() == 0)
hr =
return hr;

STDAPI_(void) DllAddRef()

STDAPI_(void) DllRelease()

STDAPI_(BOOL) DllMain(_In_opt_HINSTANCEhinst, DWORDreason, _In_opt_void*)
if (reason == DLL_PROCESS_ATTACH)
return TRUE;


First you need to copy your *ProxyStub.dll and your *Broker.dll to a place that the WinRT app can access (like c:\windows\system32) otherwise you will get E_ACCESSDENIED when trying to call object from WinRT.

To register the broker I created a custom registry script containing the following.  Notice the GUID used here matches the one I generated for the ProxyEntry.c file earlier.

Windows Registry Editor Version 5.00



Running this from administrator command prompt makes it possible for WinRT to construct your runtime class.  You may need to take ownership of the WindowsRuntime part of the registry in order to do this.  There is a tool floating around called TakeRegistryAdminOwnership.exe that can help with this.

You may also need to install the VC++ debug C++ runtime bits (vcruntime140d.dll and ucrtbased.dll) if you have not already installed that on your test machine.  Use depends.exe to find out what else the proxy and broker are dependent on if they still refuse to load.

C# App

To test out my new brokered service I created a blank C# windows application and added a reference to the generated Microsoft.Service.Sample.winmd file, then added the following lines:

            var service = new Microsoft.Service.Sample.MyService();

When you run these lines the MyServiceBroker.dll is loaded into the RuntimeBroker.exe process (you can attach to that process using your VS debugger and watch it happen and you can debug your broker that way also).  You will see RPC stuff on the stack when the DoSomethingFun call comes in.  Don’t worry about terminating the RuntimeBroker.exe process, it will auto-restart.


If you need to have your broker do something async and call back to your C# application later you can easily define a new interface, implement that in C# and pass it to your broker as an argument, then the broker can call that interface.  This RPC interface will “timeout” after a minute, so you may need to repeat that process periodically or do a heartbeat kind of thing to keep it alive.  You could build a WinRT component project that wraps all this and exposes a new “Client” interface that turns all this callback stuff into C++/CX events so that it is easier to consume in your C# applications.  Your “Client” interface could also expose C++/CX properties and events so you have a nice modern interface to your new broker.