WinRT for Win32 programmers, Part II-Win32代碼移植


說好了這節要介紹Windows Store上架前的准備工作,怎么標題變成了Win32代碼移植?這不是坑爹么!
還真不是,對於Win32程序員來說,提交應用到Windows Store,你可能遇到的最大的問題就是Win32代碼移植。

我這么說是有原因的,且聽我一一道來,先看看目前的形勢:
1、我們在Win32下已經積累了多年的代碼,如果全部拋掉,在WinRT下重新造一套輪子,SQLite,ZLib這些第三方庫且不說,我們和我們公司的祖祖輩輩們一起開發的業務相關的功能庫難道也全部重寫?這個代價是不是有點大了?
2、WinRT支持部分Win32 API和部分.NET API

想到上面兩點,作為一個成熟的Win32程序員,很自然的你會想到,用老的代碼稍微組合拼湊下,看看在WinRT下能不能跑起來?
只要你運氣不是太差的話你將發現:新建了個WinRT的工程,把Win32的代碼文件拖進去,很輕松的就能編譯通過,甚至一次通過,很歡暢的跑起來了呢~沒白跟着微軟混這么多年啊!

但是得但是,你別高興的太早,因為想要提交到Windows Store,能編譯通過還不算數,還要經過微軟的“重重審核”,這其中就有一項微軟要求開發者在提交應用之前必須自己在本地審核通過的項目:Windows App Certification Kit Validate Metro style App


如果你的應用無法通過這個認證,就更無法通過微軟的審核了,而阻礙你通過認證最大的障礙就來自於Win32移植過來的代碼,這也是本文的重點所在。

提交Store之前的准備工作之Metro Style Apps 認證:
一、如何認證
1、制作安裝包:
1.1 認證的安裝包必須使用Release,使用Debug是無法通過的
1.2 右鍵主exe工程,選擇Store,Create App Package,最后提交Store是需要使用"Create a package to upload to the Store or to use locally"進行打包的,但是認證的話使用"Create a package to use locally only"也是可以的





制作好安裝包后,直接點擊"Launch Windows App Certification Kit"按鈕,就能開始認證了,類似下圖,在對你的應用一陣蹂躪后你就能得到認證結果了:

這個方法是最簡單的,但有時候會出問題,所以我下面介紹下手動安裝和認證的方法

2、手動安裝
2.1 制作出來的安裝包目錄下,會有一個Add-AppxDevPackage.bat文件,以管理員權限運行,就能安裝了

PS. 雖然這個步驟很簡單,但還是可以有些詭異的問題,大家留意下下面這兩點
2.2 安裝包所在的路徑如果包含中文會導致安裝失敗
2.3 如果你是從別的機器拿過來的安裝包,那么你可能由於沒有開發者證書而導致安裝失敗
解決方法:打開VS,新建一個工程,編譯時會出現提示讓你申請開發者證書,按提示輸入Live ID就可以了;
其實還有不用安裝VS就可以獲取Live ID的方法,這個就另外找地方再給大家介紹了

3、手動認證
3.1 從Charm中搜索應用程序,找到Windows App Cert Kit,運行

3.2 選擇Validate Metro style App,進入后找到你的應用,選中,然后開始跑認證


點下“Next”,又是一陣蹂躪之后,你就能得到想要的認證結果了

二、認證結果的分析
認證過程其實比較簡單,認證結果是一個xml文件,我們需要的是全部PASS。


如果有Failed的項就需要根據提示來進行修正,然后重新編包,重新認證,直到認證通過為止。
而今天我們要說的最重要的部分,就在於,認證結果中的Use of Supported Platform APIs這個部分,如果認證不通過應該怎么處理?

1、為什么認證會不通過
其實字面意思已經很清楚了,就是使用了這些不被支持的API導致的,那究竟哪些函數是被支持的呢?
微軟的網站上面有詳細的API列表,大家可以查閱:
Win32 and COM for Metro style apps
上面的鏈接比較分散,我當初在做移植時專門做了個簡單的拼接,方便查閱:[轉載][合集]Win32 and COM for Metro style apps

2、怎樣認證通過
把不被支持的函數換成被支持的,或者去掉不被支持的函數調用,改用WinRT自己的API。
說的很簡單,有些事情做起來可能那么輕松,我這里列出一些簡單的函數移植對應關系:

CreateEvent->CreateEventEx
CreateFileW->CreateFile2
CreateMutexW->CreateMutexEx
WaitForSingleObject->WaitForSingleObjectEx
GetTickCount->(DWORD)GetTickCount64
DeleteFileA->DeleteFileW
FormatMessageA->FormatMessageW
GetDiskFreeSpaceA->GetDiskFreeSpaceW
GetFileAttributes->GetFileAttributesEx
GetFileSize->GetFileInformationByHandleEx
GetFullPathName-> :(
GetTempPathA-> :(
GetVersionExW-> :(
InitializeCriticalSection->InitializeCriticalSectionEx
LoadLibrary->don't use this at best,alothough ther is LoadPackagedLibrary can use
LockFile->LockFileEx
UnLockFile->UnLockFileEx
OutputDebugStringA-> don't use
SetFilePointer->SetFilePointerEx
SetThreadPriority-> :(

可以看到,不是所有函數都有直接可以替換的函數,更有像socket這類API,整套API WinRT都不允許你使用,這種你只能使用WinRT自己提供的那套新API來替換了。

關於Win32下的開源代碼庫
類似ZLib這種優秀的開源代碼,一個字都不用改就能直接在WinRT下編譯通過且順利通過認證,他們的優勢在於代碼使用純C標准庫實現;
而像SQLite這樣的使用了部分Windows API的開源庫,想要通過WinRT認證就得費點心思了,好在SQLite團隊已經開始進行這件事情,大家着急的話可以自己從這里找到並下載SQLite的WinRT分支代碼:http://www.sqlite.org/src/timeline?r=winrt 截至目前(2012/5/7 11:55)SQLite的WinRT分支還沒合入trunk

自己的開發的代碼庫就更得自己移植了
我們當時移植的過程中,被折磨的最殘的是對socket的支持,上面說到WinRT不允許使用WinSock,而我們的底層是基於異步socket的,為了平滑的移植我們的底層庫,我們用StreamSocket這樣的“高級”API適配出了“低級”的socket,這個惡心的過程以及這塊的代碼另外找機會再和大家分享交流。

小結:
很多跨平台移植性好的代碼還是能很容易的移植到WinRT上,對於Win32程序員來說絕對是個好消息,這里也提醒大家在寫跨平台代碼時還是盡可能的使用C標准庫的函數,這樣在進行跨平台移植時才能做到事半功倍。

更詳細的提交應用到Windows Store的細節和注意事項,都可以參考微軟的官方文檔:
Selling apps
Certification requirements for Windows apps


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM