Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't load WinRT Component unless I reference the project

I'm running into an odd problem. I created a Windows Runtime Component (for Windows Store) that makes some legacy C/C++ code available to .NET via some C# wrapper classes.

I wrote a test harness Store App (hereafter referred to as "test1") that references the WRC project (both projects in the same solution). It calls into the component and everything works fine.

Next I take the following output files from the WRC project:

MyWrtComponent.dll
MyWrtComponent.exp
MyWrtComponent.pdb
MyWrtComponent.pri
MyWrtComponent.winmd

...and try to use them from another Store app project ("test2"). In this project, instead of referencing the MyWrtComponent project, I add a reference to the .winmd file. Everything builds fine, but when I run the test2 app I get a System.IO.FileNotFound exception from mscorlib as soon as I try to use one of the C# classes implemented in MyWrtComponent:

at System.StubHelpers.StubHelpers.GetWinRTFactoryObject(IntPtr pCPCMD)
at MyWrtComponent.MyWrtClass..ctor()

The specified module could not be found.
(Exception from HRESULT: 0x8007007E)

Using release vs. debug build of the MyWrtComponent doesn't make any difference.

Running ProcMon on test2, I see several unsuccessful attempts at loading vccorlib120_app.DLL (or vccorlib120d_app.DLL if I'm building debug):

QueryOpen   F:\test2\bin\Debug\AppX\vccorlib120d_app.DLL    NAME NOT FOUND
QueryOpen   F:\test2\bin\Debug\AppX\vccorlib120d_app.DLL    NAME NOT FOUND
CreateFile  C:\Windows\SysWOW64\vccorlib120d_app.DLL    NAME NOT FOUND

I've confirmed that this file doesn't exist in my C:\Windows\SysWOW64 folder. I don't know whether that's relevant to my problem.

When I run test1, different locations are searched, and the file is found:

QueryOpen   F:\test1\bin\Debug\AppX\vccorlib120d_app.DLL    NAME NOT FOUND
CreateFile  C:\Program Files\WindowsApps\Microsoft.VCLibs.120.00.Debug_12.0.20827.3_x86__8wekyb3d8bbwe\vccorlib120d_app.dll SUCCESS

I compared the bin\Debug\AppxManifest.xml of both test projects, and noticed one important difference; test1 has the following and test2 doesn't:

<Dependencies>
  <PackageDependency Name="Microsoft.VCLibs.120.00.Debug" MinVersion="12.0.20827.3" />
</Dependencies>

If I add these three lines to the generated output of test2 and run the app, it works, but of course that's not a real fix.

Does anyone understand what's going on here? Does MyWrtComponent have a dependency that somehow isn't being communicated, or am I supposed to do something to package vccorlib120d_app.DLL along with my runtime component, or ... ?

Thanks in advance.

like image 889
Scott Smith Avatar asked Oct 24 '13 01:10

Scott Smith


People also ask

Does UWP use WinRT?

Core App (C++/WinRT) A project template for a Universal Windows Platform (UWP) app that doesn't use XAML. Instead, it uses the C++/WinRT Windows namespace header for the Windows.

Is WinRT open source?

It is 100% pure, modern C++ code. C++/WinRT is an open source project and ready for use today with Visual Studio 15 Preview and Windows 10 Anniversary Update.

What is C# WinRT?

C#/WinRT is a NuGet-packaged toolkit that provides Windows Runtime (WinRT) projection support for the C# language. A projection assembly is an interop assembly, which enables programming WinRT APIs in a natural and familiar way for the target language.

What is WinRT?

Windows Runtime (WinRT) is a platform-agnostic component and application architecture first introduced in Windows 8 and Windows Server 2012 in 2012.


1 Answers

Well, you're running into several issues here, the first one is that as your WinRT component uses C++, you need to have a reference to the Microsoft Visual C++ Runtime Package in your app, this is something that is expected to do by the end user of your component (the app developer), so to do it, right click the References folder in the Solution Explorer of the app and go to Windows->Extensions, there select Microsoft Visual C++ Runtime Package from the list of available SDKs and click Ok.

Second, if you plan to keep this component for yourself, it's better that you reference the project as it's the easier way to do, if you plan to distribute it, then you need to create a SDK to be sure that all the pieces are together, note that this is necessary for C++ WinRT components, but not for C# or VB.NET components, the reason seems to be that C++ WinRT components are splitted into metadata (WinMD file) and implementation (DLL file), and even if you put them side by side they're unable to recognize each other, while in C# and VB.NET the metadata and its implementation are on the same file (WinMD). If you want to create an SDK, then read this documentation on MSDN.

like image 166
Rafael Avatar answered Sep 30 '22 18:09

Rafael