Given a .winmd file, where can we find the real implementation DLL?
Asked Answered
C

3

5

I have question that given a .winmd file, where can we find the real implementation is? .winmd files just like a head file or dynamic library's .lib file, it doesn't contain any implementation, I curious that where is its implementation. Thanks.

Cheyenne answered 12/3, 2014 at 7:41 Comment(1)
Why do you need to know the answer to the question? Is it idle curiosity or do you have a technical need for the answer?Bolinger
R
3

You can't. A .winmd file just contains type declarations, it contains no code. It is the exact equivalent to a type library (.tlb) as used in COM Automation. The logical equivalent to a .h file in a C or C++ program.

The .tlb format was too restrictive to support WinRT and was re-engineered into .winmd, the format of the file is identical to .NET metadata and you can use .NET tooling (like ildasm.exe) to see its content. A compiler uses it to know how to generate proper code to use a WinRT component, just like a C++ compiler knows how to use a class library by #including a .h file that contains the class declarations.

And just like a .h file, it is up to you to figure out what executable file implements the types and to deploy it to the user's machine. Unless it is Windows.winmd, the one that declares all the built-in WinRT types, you'd expect the binary component to be very close to the .winmd file. Store requires you to include that binary component in your package. Ask the author of the component for help if you need assistance.

Rhetoric answered 12/3, 2014 at 9:24 Comment(2)
Thanks Hans. But how the loader knows where the real implementation code is? Get back to native world, .lib for .dll only contains instructions like "jmp _imp_xxx", and loader loads the .DLL and change the base address to make sure control flow can jump into real code, which is very similar to .winmd: if my code calls a function resides in a .winmd, loader, or some components of OS should redirect the control flow to the real code, right? How they find the real assembly?Cheyenne
Big question. It is very similar to the way reg-free COM works. Binding occurs dynamically at runtime, the loader is not involved. RoCreateInstance() is the factory function, the equivalent of the registry is the package manifest.Rhetoric
S
6

Disclaimer: This answer describes undocumented implementation details that can change at any time without prior notice.

For types defined in Windows.winmd or any .winmd in C:\windows\system32\WinMetadata, the registry will point you to the actual implementation.

Look for the name of the type at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsRuntime\ActivatableClassId\SystemSettings.DataModel.SettingsDatabase and the DllPath value will contain the DLL that implements the type.

Spangler answered 22/8, 2014 at 21:8 Comment(3)
This answer either needs a link to official documentation, or a disclaimer, that it is describing undocumented implementation details (that can change at any time, without prior notice).Gerdi
Well, sorry, without a disclaimer, this answer is dangerous. -1, I'm afraid, particularly with supported APIs being out, and having been published in an answer almost half a year before yours. A shame, all the more since you claim to work for the company that's going to have to fix applications using undocumented interfaces.Gerdi
My answer complements the previous answer. Adding a disclaimer makes sense, thank you!Spangler
R
3

You can't. A .winmd file just contains type declarations, it contains no code. It is the exact equivalent to a type library (.tlb) as used in COM Automation. The logical equivalent to a .h file in a C or C++ program.

The .tlb format was too restrictive to support WinRT and was re-engineered into .winmd, the format of the file is identical to .NET metadata and you can use .NET tooling (like ildasm.exe) to see its content. A compiler uses it to know how to generate proper code to use a WinRT component, just like a C++ compiler knows how to use a class library by #including a .h file that contains the class declarations.

And just like a .h file, it is up to you to figure out what executable file implements the types and to deploy it to the user's machine. Unless it is Windows.winmd, the one that declares all the built-in WinRT types, you'd expect the binary component to be very close to the .winmd file. Store requires you to include that binary component in your package. Ask the author of the component for help if you need assistance.

Rhetoric answered 12/3, 2014 at 9:24 Comment(2)
Thanks Hans. But how the loader knows where the real implementation code is? Get back to native world, .lib for .dll only contains instructions like "jmp _imp_xxx", and loader loads the .DLL and change the base address to make sure control flow can jump into real code, which is very similar to .winmd: if my code calls a function resides in a .winmd, loader, or some components of OS should redirect the control flow to the real code, right? How they find the real assembly?Cheyenne
Big question. It is very similar to the way reg-free COM works. Binding occurs dynamically at runtime, the loader is not involved. RoCreateInstance() is the factory function, the equivalent of the registry is the package manifest.Rhetoric
B
1

Hans is pretty much spot on. A winmd file just describes a type's shape (used for the CLR and JS language projection at runtime and the C++ compiler at compile time). At runtime, the RoActivateInstance API (or the RoGetActivationFactory API) take the type name and return an object that implements that type.

For an app specific type, the package manifest's ActivatableClassId entry describes the location of the implementation of the runtime class. For a system specific type, it's located in the registry, but the location of the type may change at any time in the future.

Bolinger answered 13/3, 2014 at 4:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.