Unable to load WinRT component if I do not reference the project

I got confused by a weird problem. I created a Windows Runtime component (for the Windows Store) that makes some legacy C / C ++ codes available for .NET through some C # shell classes.

I wrote a test application Store Store (hereinafter referred to as "test1"), which refers to a WRC project (both projects are in the same solution). It calls 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 a link to the MyWrtComponent project, I add a link to the .winmd file. Everything builds fine, but when I run the test2 application, 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 the debug assembly and debugging MyWrtComponent does not make any difference.

Running ProcMon on test2, I see several unsuccessful attempts to load vccorlib120_app.DLL (or vccorlib120d_app.DLL if I build 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 confirmed that this file does not exist in my C: \ Windows \ SysWOW64 folder. I do not know if this relates to my problem.

When I run test1, the search is done in different places 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 bin \ Debug \ AppxManifest.xml of both test projects and noticed one important difference; test1 has the following, and test2:

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

If I add these three lines to the generated test2 output and run the application, it will work, but, of course, this is not a real fix.

Does anyone understand what is going on here? MyWrtComponent has a dependency that is somehow not being transmitted, or should I do something to package vccorlib120d_app.DLL along with my runtime component or ...?

Thanks in advance.

+6
source share
2 answers

Well, here you are faced with several problems, the first one is that since your WinRT component uses C ++, you need to have a link to the Microsoft Visual C ++ Runtime package in your application, this is what is expected to make your end user component (application developer), to do this, right-click the "Links" folder in the application solution explorer and go to the "Windows-> Extensions" section, select the Microsoft Visual C ++ Runtime Package from the list of available SDKs and click "OK" .

Secondly, if you plan to save this component for yourself, it is better that you refer to the project, since this is an easier way to do it, if you plan to distribute it, then you need to create an SDK to make sure that everyone notes that this required for C ++ WinRT components, but not for C # or VB.NET components. The reason is that C ++ WinRT components are divided into metadata (WinMD file) and implementation (DLL file), and even if you put them side by side, they cannot recognize each other, and in C # and VB.NET metadata and their implementation is in a single file (WinMD). If you want to create an SDK, read this documentation on MSDN.

+14
source

Your second build violates application requirements. What is the state that the application package that you deliver to the Store has all the nested dependencies and that the application manifest lists all these dependencies. This is a strong Hell Countermeasure DLL, the store user is simply not hoping to solve the problem you are facing.

Adding a link to the .winmd file makes the compiler happy; it contains enough information to compile the source code. But the next step goes wrong, the .winmd file does not give the assembly enough information to host the application package. It cannot understand from the .winmd file that your component has additional dependencies. Your main project has no dependency on Microsoft.VCLib, as it is a managed project.

It doesn't seem like you can support appxmanifest yourself. This is just superfluous work that makes mistakes too easily, starting with the fact that they are different from the Debug vs Release build. The next VS update will lead you into trouble, it will no doubt have an update for Microsoft.VCLibs, which requires updating the version number in the manifest.

Using a project link is an easy way to always get the right package.

+4
source

Source: https://habr.com/ru/post/956610/


All Articles