locked
Problems creating WinRT Component DLL

    Question

  • Hi!

    I am playing around with creating a WinRT Component DLL. Therefore I created a component using the VS standard template (creates a component named "WinRTComponent"). If I add a reference from a C# project to my C++ WinRT component everything works fine. However, after I changed a few things I got a lot of strange error message. Here are my observations/questions:

    1. Is it possible to change the name of an existing component? If I change the class name of the component I receive either a "Method Not Found" (.ctor) exception or a "Requested Windows Runtime type '...' is not registered" exception in C#. I looked for config files with the component name in it so that I could change it after project creation. Unfortunately I did not found one.
    2. In the project directory there is a .SDF file that contains the component name. Unfortunately I cannot open it using SQL Management Studio 2008 R2. What is that .SDF file for? How can I open/edit it?
    3. How can I manually register and unregister the WinRT component? When is registration done by VS? When creating the project or during build?
    4. Is it possible to add multiple classes to one WinRT component and use all of them from e.g. C#? If I add a second ref class to the C++ DLL the compiler lets me create and use it from C#. If I run the application I get a "Requested Windows Runtime type '...' is not registered" exception in C# again.

    Of course I read the MSDN documentation about creating C++ WinRT components. Unfortunately it creates a component with a single class "for the sake of simplicity". Hm, maybe this is not the only reason...

    BTW - Rebuild all, clean, recreate the project reference - I tried that already. Unfortunately it did not help at all.

    Kind regards,
    Rainer.


    Rainer
    Sunday, October 9, 2011 7:52 AM

Answers

  • The WinRTComponent DLL tries to simplify what is otherwise a somewhat complicated machinery.

    • VS registers your WinRT component when you build your solution.  And by register, I mean it adds the information about this component into the AppX manifest of the app.
    • In order for the runtime classes inside your project to be activatable, the name of the winmd file corresponding to your WinRT component needs to match the top-level namespace of your runtime classes.

    When you use the default settings for a WinRTComponent DLL template, VS ensures that all of the above requirements are fulfilled.  It generates sources/headers with the same namespace name as the project name, which also happens to be the name of the output winmd file.

    However, when you rename the component, your output winmd has a different name but your namespace inside your code is still the old one.  They need to match.

    And, yes yoy can have multiple runtime classes in your project as long as they are in the same namespace.

    Thanks

    Raman Sharma, Visual C++

    Monday, October 10, 2011 4:58 PM

All replies

  • I'm having the exact same problem. Don't know any more than you unfortunately.
    Sunday, October 9, 2011 5:51 PM
  • As a work around, I modified the default "WinRTComponent" to have a method which returned an instance of the WinRT component I was actually interested in. This avoided the error "Requested Windows Runtime type '...' is not registered" as my C# code isn't instantiating the instance.

    Sunday, October 9, 2011 6:02 PM
  • The WinRTComponent DLL tries to simplify what is otherwise a somewhat complicated machinery.

    • VS registers your WinRT component when you build your solution.  And by register, I mean it adds the information about this component into the AppX manifest of the app.
    • In order for the runtime classes inside your project to be activatable, the name of the winmd file corresponding to your WinRT component needs to match the top-level namespace of your runtime classes.

    When you use the default settings for a WinRTComponent DLL template, VS ensures that all of the above requirements are fulfilled.  It generates sources/headers with the same namespace name as the project name, which also happens to be the name of the output winmd file.

    However, when you rename the component, your output winmd has a different name but your namespace inside your code is still the old one.  They need to match.

    And, yes yoy can have multiple runtime classes in your project as long as they are in the same namespace.

    Thanks

    Raman Sharma, Visual C++

    Monday, October 10, 2011 4:58 PM
  • Hi Raman!

    Thank you for the clarification. Multiple runtime classes in the same namespace work.

    It would be great if we would have more information about the registration process that is managed by VS behind the scenes. Maybe someone in you team could write a blog about it?

    Kind regards,
    Rainer.


    Rainer
    Tuesday, October 11, 2011 6:16 AM
  • Hi Rainer,

    Let me try to explain it a bit here.  The reason there isn't a blog post about it so far is because some of the machinery may change after the Developer Preview.  Also, VS is trying to make it as easy as possible so that developers don't need to know the details.  However, here it is for the curious :)

    As you know every Metro style app package contains a file called AppXManifest.xml.  This file "describes" your package to Windows when it installs.  It contains information about capabilities, component registrations, contract registrations, splashscreen and other such stuff.

    In that file under the tag extensions, there is a category called activatableClass using which you can register you specific components.  For example the fragment below will register your component (mycomp.dll) as a in-process WinRT component, and it also tells the OS that there is a class called myClass in your component that your app can activate.  The hidden detail is that your app package needs to contain a file called mycomp.winmd describing your component.  This is because the top-level namespace of your classes is called mycomp.

    <Extensions>

        <Extension Category="windows.activatableClass.inProcessServer">

            <InProcessServer>

                <Path>mycomp.dll</Path>

                <ActivatableClass ThreadingModel="both" ActivatableClassId="mycomp.myClass"/>

            </InProcessServer>

        </Extension>

    </Extensions>

     

    I hope this helps.

    Thanks

    Raman Sharma, Visual C++

    Tuesday, October 11, 2011 5:33 PM
  • Here's an example:

    http://video.ch9.ms/handsonlabs/build2011/707.zip

     

    Raman

    Monday, October 17, 2011 11:43 PM
  • So does that mean I could not have multiple projects implementing different classes in the same namespace?

    project#1 => native.foo.dll

    namespace native {

      public ref class Component1 sealed {};

    }

     

    project#2 => native.bar.dll

    namespace native {

      public ref class Component2 sealed {};

    }

     

    And then I would reference the 2 dlls from my WinJS project and use them in this way:

    new native.Component1; // load from native.foo.dll

    new native.Component2; // load from native.bar.dll

     

    VS will not wire that for me, so I would have to edit the extensions tag in the winJS app manifest by hand?

    Thursday, November 17, 2011 11:05 AM
  • How can we change this manifest? Isnt it compiled every time?

    • Edited by phil_ke Thursday, November 17, 2011 11:15 AM
    Thursday, November 17, 2011 11:12 AM
  • Yes as of now that is not possible (automatically).

    VS does basic wiring through already setup project templates.

    Thanks


    Raman Sharma | Program Manager, Visual C++ | @rasharm_msft

    (if my post has answered your question, please consider using the 'mark as answer' feature in the forums to help others)
    Saturday, November 19, 2011 3:09 AM