none
How to distribute native and managed libraries for Metro apps RRS feed

  • Question

  • I'm developing a user control library for XAML apps that is backed by another native library. This seems to work fine when developing an app that is in the same solution as my libraries, however when trying to reference the libraries as dlls, rather than projects, I get a run time error.

    The error occurs in GetXamlType, and is an unhandled exception saying "Requested Windows Runtime type 'MyNativeType_XamlTypeInfo.XamlMetaDataProvider' is not registered". I would expect the project to be picking this up from the native dll.

    Any idea where I'm going wrong with this?

    Wednesday, September 19, 2012 10:36 AM

Answers

  • So I've finally solved the problem.....

    The directory structure inside the VSIX package needs to be along the lines of:

    Redist\CommonConfiguration\neutral

    References\CommonConfiguration\neutral

    With CommonConfiguration being replaceable by Debug/Release, and neutral being replaceable by x86/x64/ARM if needed.

    You need to put any files that contain .NET metadata in the References tree, and any other files in the Redist tree. Placing files without .NET metadata in the References tree will cause an odd build error for any project including the Extension SDK.

    You need an SDKManifest.xml in the top level directory of the VSIX folder. This file needs to contain entries for files in the References tree. My SDKManifest.xml file looks a bit like this:

    <?xml version="1.0" encoding="utf-8" ?>
    <FileList
      DisplayName="My Component"
      ProductFamilyName="Components"
      MinVSVersion="11.0"
      MinToolsVersion="4.0"
      CopyRedistToSubDirectory="."
      AppliesTo="WindowsAppContainer+WindowsXAML+Managed"
      SupportedArchitectures="x86">
        <File Reference="MyManagedComponent.dll">
            <ContainsControls>True</ContainsControls>
        </File>
        <File Reference="MyWinRTComponent.winmd" Implementation="MyWinRTComponent.dll" />
    </FileList>

    The important bit I was missing was the implementation tag for the WinRT component. Also worth noting is the CopyRedistToSubDirectory tag. It seems that by default everything from the References tree get copied alongside your app when the extension is included. By using the CopyRedistToSubDirectory as I have, I have copied everything from the Redist folder to the same location. I tried modifying this to "MyComponent", and this meant I had to change the Implementation tag for the WinRT component to "MyComponent\MyWinRTComponent.dll".

    As I mentioned in a previous post the VSIX project template seems pretty useless. You have to do most of the work yourself. No SDKManifest.xml is created, and if you add other projects as Assets, then they don't get put into the correct locations in the output VSIX file. As such I wouldn't recommend using project references from a VSIX project. This means you have to copy the resources into the correct place yourself (with a batch file or a pre-build step), and add them into the VSIX project yourself, in the correct directories.

    Hopefully this will help anyone avoid the pain I've had dealing with this over the past few days. If anyone else has any questions please post.


    • Marked as answer by D.G.Thomas Tuesday, September 25, 2012 3:40 PM
    Tuesday, September 25, 2012 3:40 PM

All replies

  • So it seems that I need to directly reference the .winmd file for the native .dll. The .winmd file is what provides the Windows Runtime type. I've done this by packaging my managed .dll, my "native" .winmd file, and my native .dll into an Extension SDK with a bit of help from this blog: http://timheuer.com/blog/archive/2012/03/07/creating-custom-controls-for-metro-style-apps.aspx.

    Unfortunately I'm now hitting a more impenetrable issue. On attempting to build a sample project which references my Extension SDK I get the following error: "Xaml Internal Error error WMC9999: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B).".

    Doing a bit of research about this error suggests that it tends to be an x86 vs x64 issue, except that I'm building everything for x86. I also wouldn't expect that anything I have written would get loaded at build time. From previous errors I've got I'm pretty confident that my managed .dll, and my .winmd file are being inspected correctly, and I wouldn't have thought anything would need to look at the native .dll till load time.

    Any thoughts?

    Thursday, September 20, 2012 2:13 PM
  • I've got another version of my project that does not depend on a native .dll, but just consists of a managed .dll. This seems to work fine, suggesting the problem is with the native.dll or the .winmd file. Still not sure what's wrong though.
    Thursday, September 20, 2012 3:16 PM
  • I've explored a bit further with this and discovered a bit more, but I still haven't got anything much working. The XAML error I described before was occurring because I had a native .dll in the references folder. Regardless of where I move my .native dll and my .winmd file, I get the error that I had in my original post. This seems to be occurring because the .winmd file cannot be found (I've tested this by deleting the .winmd file and checking for the same error).

    This page is helpful but does not contain all the information I need: http://msdn.microsoft.com/en-us/library/hh768146.aspx

    This page does exactly what I want but is broken: http://msdn.microsoft.com/en-us/library/jj127117.aspx

    This page is just completely wrong: http://msdn.microsoft.com/en-us/library/dd393742.aspx. The VSIX project templates don't seem to create anything required for a VSIX package (such as the SDKManifest.xml).

    Is there any support for VSIX package with native .dlls in Visual Studio 2012?

    Tuesday, September 25, 2012 1:48 PM
  • So I've finally solved the problem.....

    The directory structure inside the VSIX package needs to be along the lines of:

    Redist\CommonConfiguration\neutral

    References\CommonConfiguration\neutral

    With CommonConfiguration being replaceable by Debug/Release, and neutral being replaceable by x86/x64/ARM if needed.

    You need to put any files that contain .NET metadata in the References tree, and any other files in the Redist tree. Placing files without .NET metadata in the References tree will cause an odd build error for any project including the Extension SDK.

    You need an SDKManifest.xml in the top level directory of the VSIX folder. This file needs to contain entries for files in the References tree. My SDKManifest.xml file looks a bit like this:

    <?xml version="1.0" encoding="utf-8" ?>
    <FileList
      DisplayName="My Component"
      ProductFamilyName="Components"
      MinVSVersion="11.0"
      MinToolsVersion="4.0"
      CopyRedistToSubDirectory="."
      AppliesTo="WindowsAppContainer+WindowsXAML+Managed"
      SupportedArchitectures="x86">
        <File Reference="MyManagedComponent.dll">
            <ContainsControls>True</ContainsControls>
        </File>
        <File Reference="MyWinRTComponent.winmd" Implementation="MyWinRTComponent.dll" />
    </FileList>

    The important bit I was missing was the implementation tag for the WinRT component. Also worth noting is the CopyRedistToSubDirectory tag. It seems that by default everything from the References tree get copied alongside your app when the extension is included. By using the CopyRedistToSubDirectory as I have, I have copied everything from the Redist folder to the same location. I tried modifying this to "MyComponent", and this meant I had to change the Implementation tag for the WinRT component to "MyComponent\MyWinRTComponent.dll".

    As I mentioned in a previous post the VSIX project template seems pretty useless. You have to do most of the work yourself. No SDKManifest.xml is created, and if you add other projects as Assets, then they don't get put into the correct locations in the output VSIX file. As such I wouldn't recommend using project references from a VSIX project. This means you have to copy the resources into the correct place yourself (with a batch file or a pre-build step), and add them into the VSIX project yourself, in the correct directories.

    Hopefully this will help anyone avoid the pain I've had dealing with this over the past few days. If anyone else has any questions please post.


    • Marked as answer by D.G.Thomas Tuesday, September 25, 2012 3:40 PM
    Tuesday, September 25, 2012 3:40 PM