除非我引用项目,否则无法加载WinRT组件

我遇到了一个奇怪的问题。 我创建了一个Windows运行时组件(用于Windowsapp store),它通过一些C#包装器类为.NET提供了一些旧的C / C ++代码。

我编写了一个测试工具Store App(以下简称“test1”),它引用了WRC 项目 (两个项目都在同一个解决方案中)。 它调用组件,一切正常。

接下来,我从WRC项目中获取以下输出文件:

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

…并尝试从其他商店应用项目(“test2”)使用它们。 在这个项目中,我添加了对.winmd文件的引用,而不是引用MyWrtComponent项目。 一切都很好,但是当我运行test2应用程序时,一旦我尝试使用MyWrtComponent中实现的一个C#类,我就会从mscorlib获得一个System.IO.FileNotFoundexception:

 at System.StubHelpers.StubHelpers.GetWinRTFactoryObject(IntPtr pCPCMD) at MyWrtComponent.MyWrtClass..ctor() The specified module could not be found. (Exception from HRESULT: 0x8007007E) 

使用MyWrtComponent的发布与调试版本没有任何区别。

在test2上运行ProcMon,我看到几次加载vccorlib120_app.DLL(或者如果我正在构建调试时为vccorlib120d_app.DLL)的尝试失败:

 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 

我已经确认我的C:\ Windows \ SysWOW64文件夹中不存在此文件。 我不知道这是否与我的问题有关。

当我运行test1时,会搜索不同的位置,并找到该文件:

 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 

我比较了两个测试项目的bin \ Debug \ AppxManifest.xml,并注意到一个重要的区别; test1有以下内容,test2没有:

    

如果我将这三行添加到test2的生成输出并运行应用程序,它可以工作,但当然这不是一个真正的修复。

有谁知道这里发生了什么? MyWrtComponent是否具有以某种方式未被通信的依赖关系,或者我应该做什么来将vccorlib120d_app.DLL与我的运行时组件一起打包,或者……?

提前致谢。

好吧,你在这里遇到了几个问题,第一个是因为你的WinRT组件使用C ++,你需要在你的应用程序中引用Microsoft Visual C ++运行时包,这是预期由组件的最终用户(应用程序开发人员),为此,右键单击应用程序的解决方案资源管理器中的References文件夹,然后转到Windows-> Extensions,从可用SDK列表中选择Microsoft Visual C ++ Runtime Package,单击确定。

其次,如果你打算自己保留这个组件,最好引用项目,因为它是更简单的方法,如果你打算分发它,那么你需要创建一个SDK来确保所有的部分都在一起,请注意,这对于C ++ WinRT组件是必需的,但不适用于C#或VB.NET组件,原因似乎是C ++ WinRT组件被拆分为元数据(WinMD文件)和实现(DLL文件),即使你放了它们并排在一起它们无法识别彼此,而在C#和VB.NET中,元数据及其实现都在同一个文件(WinMD)上。 如果要创建SDK,请在MSDN上阅读此文档 。

您的第二次构建违反了app-package要求。 您向Store发送的应用程序包具有嵌入的所有依赖项以及应用程序清单列出所有这些依赖项的状态。 这是一个强大的DLL Hell对策,Store用户只是没有希望解决你遇到的那种问题。

添加对.winmd文件的引用可使编译器满意,它包含足够的信息来编译源代码。 但是下一步出错了.winmd文件没有为构建系统提供足够的信息来将应用程序包放在一起。 它无法从.winmd文件中找出您的组件具有其他依赖项。 您的主项目不依赖于Microsoft.VCLibs,因为它是一个托管项目。

这并不是说你不能自己维护appxmanifest。 它只是额外的工作,这很容易出错,从它们与Debug和Release版本不同开始。 下一个VS更新将让您遇到麻烦,毫无疑问它会有Microsoft.VCLibs的更新,要求您更新清单中的版本号。

使用项目引用是始终获得正确包的简单方法。