Cheat-Sheet for using Brokered Windows Runtime Components for side-loaded Windows Store apps
Starting with the Windows 8.1 Update that was announced at //Build 2014, the functionality of performing “Inter Process Communication” – which is commonly referenced to as “IPC” between a side-loaded Windows Store app and a Desktop process has been enabled to leverage existing “desktop” code.
Please note that this IPC functionality has only been introduced for “side-loaded” Windows Store apps and is still NOT supported for apps that are published to the Store.
The Whitepaper on “Brokered Windows Runtime Components for side-loaded Windows Store apps” has been published here: http://msdn.microsoft.com/en-us/library/windows/apps/dn630195.aspx that goes through the nitty-gritty details of the steps required to to enable a side-loaded Windows Store app to communicate with a desktop process.
This blog will provide you with a checklist of things you need to keep in mind when implementing this solution/scenario.
The “official” samples for the Enterprise side-loading scenario are available for download through the following links:
- Server & Proxy Component: http://code.msdn.microsoft.com/windowsapps/Brokered-Windows-Runtime-9d64cada
- Client Component: http://code.msdn.microsoft.com/windowsapps/Brokered-Windows-Runtime-74899ea2
I am also including a “sample” HelloWorldIPC app with this blog (see below) that performs the basic calculator operations of Add, Subtract, Divide and Multiply. There is also an AddAsync function that simulates a very complex Math operation of adding two numbers by introducing a delay :) [but the idea is to show how to perform an async operation that takes a while to process]
There are a total of 3 types of projects you need to create to have the right plumbing in place. First, let’s start with what you will need and why you need it.
1.) Server component – Windows Runtime Component with reference additions to run/reference desktop code
The server component is the part of your IPC solution that will be running traditional desktop code that cannot be run from a Windows Store app. For example, if your existing desktop code is accessing a SQL database or using the System.Data namespace, then this is the project you need all of your desktop code to run under.
To create a Server component, you need to start by creating a Windows Runtime Component project from which you can reference the typical WinRT code. You also have to realize that you can only write this Server component project in C#.
But wait, if the server component is a Windows Runtime Component, how can one use desktop code?
The key to this answer lies in the fact that now you can add references to the desktop DLL’s – such as System.Data.dll or System.dll by opening the .csproj file in your favorite text editor (notepad). Here’s an example of the section you will need to add to your server.csproj file.
<ItemGroup> <!---These references should be considered "infrastructure" references and should be used exactly as described --> <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.dll" /> ... etc ... </ItemGroup>
2.) Client – Windows Store app project with manifest changes to reference the Server Component
The client component is a typical Windows Store app project that will now reference this Server component by adding a “Reference” to it and also include a configuration section in its package.appxmanifest file that declares the namespace and class of the server component and the location where the server component resides at runtime. To add the configuration section to your manifest file, you can open the manifest file in Visual Studio by right clicking the manifest file and choose “View Code” and then insert the following section in it:
<Extension Category="windows.activatableClass.inProcessServer"> <InProcessServer> <Path>clrhost.dll</Path> <ActivatableClass ActivatableClassId="Server_NameSpace.Server_Class" ThreadingModel="both"> <ActivatableClassAttribute Name="DesktopApplicationPath" Type="string" Value="path_to_the_compiled_server_winmd_file_and_proxy.dll" /> </ActivatableClass> </InProcessServer> </Extension>
In addition to adding the configuration changes to reference the server component at runtime, you will also need to “Add Reference” to the Server.winmd component. Adding a reference to the server component will allow your client side project to “reference” your server project – in other words, you can create an instance of the server and invoke the methods exposed by the server class and hence add compile time support. There are two winmd files that get generated when the server project is compiled, so you need to carefully select the “reference” version of the winmd component. This topic is discussed below.
3.) Proxy – Win32 DLL to generate a proxy stub to enable the Client/Server communication
At runtime, when the side-loaded Windows Store app references the server component by doing a “new ServerClass()” and then when the ServerClassInstance.Method is called, you will wonder how will the system “invoke” the call and who is responsible for marshaling the calls between the Client and Server. For Windows to tunnel the request from the client to the server, you will need to provide a proxy object and register this proxy with the system so that the system knows that the side-loaded Windows Store app is trying to reference a server component and launch a DLLHost.exe process to host the server component.
If you fail to do this step, then your sideloading will not work.
You will need to compile the server project initially to generate the winmd file that the client side can “Add Reference” to. Notice that the server component project has a set of “Post Build” events that generates two types of WinMD files as well as generates the proxy .c and .h files (by running MIDL). The server project compile directory will contain two folders “impl” and “reference” and inside these folders you will find the server.winmd files. Notice the size of these files, the reference\server.winmd file is smaller in size than impl\server.winmd because it only contains the declarations of your server component and leaves the implementation out.
When you “Add reference” to the server component from your client side project, you need to reference the winmd file from the “reference” folder (not the “impl” folder). The winmd file in the “impl” folder will be used at runtime. After you add reference to the server implementation, you can start coding your client side project and reference the server component by creating an instance of the server component and calling methods on it, just as you would reference any other namespace/class/methods in the Windows Runtime. Once the client project compiles successfully and you want to run the project, there are a couple more steps to follow to ensure that the “runtime” behavior is as expected and the server component “actually” gets called.
To enable the runtime behavior, all you need to do is copy the impl\server.winmd file alongwith the Proxy.dll file (that was generated by compiling the proxy project). You need to copy these two files to the path that you have added to the client project’s application manifest file. In the example above, this path is the Value=”path_to_the_compiled_server_winmd_file_and_proxy.dll”. After copying the files to this path, you also need to grant permissions to the “ALL APPLICATION PACKAGES” user on that folder by running the command:
icacls . /T /grant "ALL APPLICATION PACKAGES":RX
Now that the permissions are set, you will also need to “register” your Proxy.dll with the system by running the command:
At this point your client side project can call into the server component.
To notice whether you have the right plumbing in place at runtime, you can check the following:
- When the client references the server component by performing a “new ServerClass”, the system will launch a system provided “DLLHost.exe”
- In this “DLLHost.exe”, you should also notice your “Proxy.DLL” being loaded. You can see what DLL’s have been loaded in a process by using the Process Explorer tool from SysInternals website.
- Similarly, the “Proxy.DLL” file should also be loaded in your client side project.
- If you notice the Proxy.DLL file is only loaded in the server component and not your side-loaded application, then it would mean that you have not given the right permissions (see the icacls command above).
- If the Proxy.DLL is not loaded at all in either process, then it means you have not registered your proxy with the system (see the Regsvr command above).
Hopefully this blog helps you reference your “desktop” code from a side-loaded Windows Store app using the new Brokered Windows Runtime components.
Comments are welcome both below and on our team’s Twitter handle @WSDevSol.