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:

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:

regsvr32 Proxy.dll

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.

HelloWorldIPC.zip

Comments (8)

  1. ShawnFeatherly says:

    Took me a while to figure out that before you can add the desktop DLL's to the xml of the *.csproj file, you need to add <ImplicitlyExpandTargetFramework>false</ImplicitlyExpandTargetFramework> in the first PropertyGroup, right under <ProjectTypeGuids> works.

  2. Jason A. says:

    Hi all.  We're running our app on a tablet that has a 64 bit processor and a 32 bit version of Windows 8.1.  When I go to do the regsvr32, it gives me this error:  "The module HelloWorldProxy.dll" failed to load.  Make sure the binary …  The specified module could not be found.  I've Googled and the only thing I can find that seems useful suggests there is a 32 bit/64 bit mismatch but I can't seem to find out how to solve it.  Any ideas?

  3. Upkar says:

    Hi Jason,

    You need to copy the file mvscr120d.dll to the folder where this HelloWorldProxy.dll resides. After copying this dll you will be able to run regsvr command successfully. You can look for this dll (32 bit) on google.

    Thanks!

  4. Upkar says:

    The sample works fine on my local machine but when i deploy it on test device i see a following error:-

    "Unable to cast COM object of type 'HelloWorldServerComponent.Calculator' to interface type 'HelloWorldServerComponent.ICalculator'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{D11FEE62-FDC8-4509-8672-3E9C1264EDAB}' failed due to the following error: The specified module could not be found. (Exception from HRESULT: 0x8007007E).

    I performed similar steps on this test machine as done on local machine but still it fails.

    Can you please let me know how can I make it work on test machine?

    Thanks!

  5. Francisco says:

    I can register the proxy dll in my laptop, but I can't in the physical device (winRT)….

    how can I do??

  6. Ted says:

    @Upkar

    Did you ever find a solution? I am having the same problem.

  7. Lance says:

    When I try to register the proxy.dll to other device, I'm getting the following error:

    The module "Proxy.dll" failed to load. Make sure the binary is stored at the specified path or debug it to check for problems with the binary or dependent .DLL files. The specified module could not be found.

    I also used the dependency walker program to check the dependencies of the proxy.dll. I saw that there's a dependency on C:WindowsSystem32VCRUNTIME140D.dll. That dll is not in System32 folder. There's a VCRUNTIME140.dll file but there's no VCRUNTIME140D.dll. that's probably the reason why I'm failing to register the proxy.dll. VCRUNTIME140D.dll, I guess is the dll being used when you are debugging. But since we're on anther device that doesn't have a development environment there's no VCRUNTIME140D.dll present. Now the question is, how will I prepare the brokered component dll for deployment to other devices that doesn't have development/debug environment. I'm actually making an installer for my brokered component dll? I'm failing when I'm trying to invoke regsvr32 Proxy.dll.

  8. Lance says:

    You need to install VC_REDIST to the client before you can register the proxy.dll.

    You can download it from here:

    http://www.microsoft.com/…/details.aspx

Skip to main content