6

我遇到了一個奇怪的問題。我創建了一個Windows運行時組件(用於Windows應用商店),它通過一些C#包裝類將一些傳統的C/C++代碼提供給.NET。無法加載WinRT組件,除非我參考項目

我編寫了一個參考WRC 項目(兩個項目都在同一解決方案中)的測試工具Store App(以下簡稱爲「test1」)。它調用組件,一切正常。

接下來我把下面的輸出文件從WRC項目:

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

...並嘗試從另一個商店應用工程(「測試2」)中使用它們。在這個項目中,我沒有引用MyWrtComponent項目,而是添加了對.winmd文件的引用。一切都建立很好,但是當我運行test2的應用程序,我只要我嘗試使用MyWrtComponent實施了C#類之一得到的mscorlib一個System.IO.FileNotFound例外:

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文件夾中。我不知道這是否與我的問題有關。

當我運行測試1,不同的地點進行搜索,並找到該文件:

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 \兩個測試項目的調試\ AppxManifest.xml,並注意到一個重要的區別; test1的有以下和TEST2並不:

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

如果我添加這三條線來測試2的生成的輸出和運行應用程序,它的工作原理,但當然這不是一個真正的解決。

有沒有人知道這裏發生了什麼? MyWrtComponent是否具有某種程度上沒有傳遞的依賴關係,或者我應該做些什麼來將vccorlib120d_app.DLL與我的運行時組件一起打包,或者......?

在此先感謝。

回答

14

好吧,您在這裏遇到了幾個問題,第一個是因爲您的WinRT組件使用C++,所以您需要在應用程序中引用Microsoft Visual C++運行時包,這是預期的由組件的最終用戶(應用程序開發人員)執行,所以要執行此操作,請右鍵單擊應用程序的解決方案資源管理器中的References文件夾,然後轉到Windows-> Extensions,然後從列表中選擇Microsoft Visual C++ Runtime Package的可用SDK並單擊確定。其次,如果您打算爲自己保留這個組件,那麼您最好引用該項目,因爲如果您打算分發它,那麼您需要創建一個SDK以確保所有項目這些部分在一起,請注意,這對於C++ WinRT組件是必要的,但對於C#或VB.NET組件來說不是必需的,原因似乎是C++ WinRT組件被拆分爲元數據(WinMD文件)和實現(DLL文件),並且即使將它們並排放置,它們也無法識別對方,而在C#和VB.NET中,元數據及其實現在同一個文件(WinMD)上。如果您想創建SDK,請在MSDN上閱讀this documentation

4

您的第二次構建違反了應用程序包要求。其中說明您交付給應用商店的應用程序包已嵌入全部,並且應用程序清單列出了所有這些依賴關係。這是一個強大的DLL地獄對策,Store用戶根本沒有希望解決你遇到的那種問題。

向.winmd文件添加引用可使編譯器保持高興,它包含足夠的信息來編譯源代碼。但下一步出錯了,.winmd文件不會給構建系統提供足夠的信息來將應用程序包放在一起。它不能從.winmd文件中找出組件具有附加依賴關係。您的主項目不受Microsoft.VCLibs的依賴,因爲它是一個託管項目。

這不像你不能自己維護appxmanifest。它只是額外的工作,很容易出錯,從調試與發佈構建的不同開始。下一次VS更新會讓你陷入麻煩,毫無疑問,它會有Microsoft.VCLibs的更新,要求你更新清單中的版本號。

使用項目引用是始終獲取正確包的簡單方法。

+0

我已經提出了兩個答案,但我必須選擇一個爲賞金,拉斐爾的答案有具體的指示,這對我有幫助。感謝Hans。 –