天天看點

WM有約II(九):再談部署

WM有約II(九):再談部署

Written by Allen Lee

當多語言應用程式遇到CabWiz……

      建立安裝包的方法非常簡單,如果你對此沒有了解,我建議你先去閱讀《WM有約(五):部署應用程式》。安裝包建立好後,拿到模拟器裡安裝,安裝好後,你可以在"開始"菜單的"程式"裡找到應用程式的圖示:

WM有約II(九):再談部署

圖 1

因為我們在簡體中文系統上運作應用程式,而簡體中文又是應用程式支援的語言,是以應用程式會使用簡體中文作為目前語言:

WM有約II(九):再談部署

圖 2

由于簡體中文系統也支援英文,當我們在選項窗體裡把目前語言改為英文時,應用程式應該能夠正确顯示英文界面,然而,事實并非如此!

WM有約II(九):再談部署

圖 3

問題究竟出在哪裡?是目前語言設定出錯嗎?我修改代碼,通過MessageBox顯示目前語言,發現已被正确設為英文。當我通過Visual Studio部署到模拟器時,一切正常,而當我通過安裝包部署到模拟器時,英文界面就變成上面這樣了,這意味着資源檔案本身應該是沒問題的,但安裝包裡的資源檔案可能出錯或者損壞了。我不知道有沒有第三方的安裝包建立工具,如果沒有的話怎麼辦?難道無法為多語言應用程式建立安裝包?

      在Windows Mobile 6 SDK文檔裡找到這麼一段話:

Files that are packaged into a .cab file to be installed on a device are stored by file name, without regard to their installation directory. For this reason, if multiple files within a .cab are given the same name but different install directories, only one of the files will be installed in all locations. To work around this behavior, be sure to use unique names for all files within a single .cab file.

這麼看來,CabWiz在建立安裝包的時候,誤把簡體中文和英文資源檔案看作一樣的了,因為它們的名字是一樣的。怎麼解決這個問題?Jose A. Garcia Guirado給出了解決方案:

  • 《Survival guide to do resource localization using Compact Framework 2.0》

你可以按照他的方法手動修改INF檔案和運作CabWiz,也可以使用他的工具自動化這個過程。建立好正确的安裝包後,拿到模拟器裡測試,這次就正常了:

WM有約II(九):再談部署

圖 4

值得提醒的是,如果你修改了應用程式,想重新建立安裝包,你可以在指令行裡運作CabWiz,并向它傳遞修正的INF檔案,或者使用Jose在上面那篇文章裡提到的方法,不要重新編譯安裝包項目,因為這樣會覆寫修正的INF檔案,并産生有問題的安裝包。

讓部署更簡便

      對于資深WM玩家來說,程式員的任務已經結束了,然而,如果你讓普通WM使用者把CAB檔案拿到手機裡安裝,他們要麼用問題轟炸你,要麼把應用程式打進冷宮,顯然,這些都不是你想要的結果,怎麼辦?

一個辦法是為應用程式建立一個MSI安裝程式,協助使用者把應用程式安裝到手機裡,怎麼建立呢?Christopher Tacke寫了一篇文章,詳述整個建立過程:

  • 《Deploying .NET Compact Framework 2.0 Applications with .cab and .msi Files》

然而,這個過程非常繁瑣,雖然客戶樂了,可也不能苦了程式員,再說,這個辦法會把包含Custom Action的DLL安裝到桌面電腦裡,顯得有點多餘,說白了,它其實就是調用CeAppMgr.exe,并把描述應用程式的INI檔案作為參數傳給它,這樣的話,為什麼不直接建立一個簡單的應用程式來執行這個任務呢?

      于是,我用Expression Blend建立了一個Cab Installer:

WM有約II(九):再談部署

圖 5

Cab Installer在啟動時會判斷ActiveSync是否已經安裝,如果沒有安裝,它會禁用Install按鈕:

WM有約II(九):再談部署

代碼 1

而CeAppManager則通過查找系統資料庫來确定CeAppMgr.exe是否已經安裝:

WM有約II(九):再談部署

代碼 2

當使用者單擊Install按鈕時,Cab Installer會調用CeAppManager.Install方法來安裝應用程式,為了避免使用者多次單擊Install按鈕,Cab Installer在調用CeAppManager.Install方法後會禁用Install按鈕:

WM有約II(九):再談部署

代碼 3

而CeAppManager.Install方法則負責啟動CeAppMgr.exe,并把INI檔案的完整路徑傳給它:

WM有約II(九):再談部署

代碼 4

      編譯Cab Installer項目,把CabInstaller.exe、Trombone.cab和Trombone.ini三個檔案放在同一個檔案夾裡,然後運作CabInstaller.exe。當使用者單擊Install按鈕時,Cab Installer将會啟動CeAppMgr.exe來完成後續工作:

WM有約II(九):再談部署

圖 6

      目前,Cab Installer和應用程式緊密耦合,不過,要讓它服務其它應用程式也是很容易的,我們也可以把它改成通用安裝程式,通過配置檔案來指定應用程式的圖示和名稱、安裝程式上顯示的文字以及Cab檔案等。說到這裡,你可能會問:"能否通過它來部署.NET Compact Framework?"我試了一下,答案是可以的,但我不知道如何獲知目标裝置是否已經安裝了所需版本的.NET Compact Framework,這可能會導緻重複安裝,如果有辦法擷取這個資訊,那麼Cab Installer就有一般化的價值了。

尼古丁解決方案

      既然安裝了應用程式,不妨運作一下,看看上次的本地化是否足夠徹底。噢,有點不妥:

WM有約II(九):再談部署

圖 7

這個日期和時間格式是英文的,檢視DateTimePicker的屬性視窗,發現這個格式是當初寫死進去的,怎麼處理?一個辦法是通過CultureInfo.DateTimeFormatInfo擷取格式資訊,并設定DateTimePicker.CustomFormat屬性:

WM有約II(九):再談部署

代碼 5

修改一下主窗體的構造函數,然後重新部署應用程式,再來看看運作效果:

WM有約II(九):再談部署

圖 8

WM有約II(九):再談部署

圖 9

簡體中文的格式沒問題了,卻輪到英文的格式出問題了!為什麼會這樣?原來,DateTimePicker隻是使用我們提供的格式,而格式裡面指代的"上午符号"和"下午符号"則從裝置的區域設定裡擷取,假如我們在裝置的區域設定裡把它們分别設為"OK"和"KO",那麼我們的應用程式也會跟着改:

WM有約II(九):再談部署

圖 10

.NET Compact Framework的區域設定是基于每個裝置而不是每個線程的,而我們的應用程式卻允許不同于裝置的區域設定,于是出現了假設性沖突,怎麼處理?既然我們的假設和.NET Compact Framework的有沖突,那就惟有放棄使用它提供的日期和時間格式,我們可以把這個格式放在對應的資源檔案裡,然後在目前語言更改時把它讀到DateTimePicker.CustomFormat屬性。

      這個辦法雖然解決了我們的問題,卻引入了另一個問題,就是從今以後我們要自己管理日期和時間的格式了,這不禁讓我想起溫伯格在《你的燈亮着嗎?》裡的一句話:

每種解決方案都會帶來新的問題。

從本質上來說,我們沒有解決問題,而是對它應用"變換"和"轉移"這兩種操作,正如溫伯格在《你的燈亮着嗎?》裡說的:

有時候,我們使問題變得不那麼棘手,其實隻是把問題放在"别人家的後院兒裡"。

溫伯格把這種技巧叫做"轉嫁問題",事實上,我們每天都和"轉嫁問題"打交道,當客戶把項目交給你時,他其實是在使用"轉嫁問題",隻不過他需要為此付你報酬,從這點來看,"轉嫁問題"實質上是"價值交換",正因為這些層出不窮的問題,人類社會才得以延續下去。

      "轉嫁問題"有一個有趣的推論,QQ空間的搶車位是這個推論的其中一個完美的展現。這個遊戲是免費的,除了你的時間之外,它"似乎"無需其它支出,縱觀到目前為止的衆多更新,你不難發現它在努力建立一個更好的"競争視圖",你可以很友善地看到自己在整個圈子裡處于一個什麼競争狀态,利用人的攀比心态是騰訊成功的秘訣之一,當大家都沉浸在這個遊戲裡時,它推出了"管家服務",如果你沒空停車,但又不希望排名落後于他人,那麼你可以通過支付一定的費用雇傭管家來幫你停車,免除你的煩惱,這是一個非常水到渠成的解決方案,然而,當你沉浸在這個遊戲裡時,你怎麼也想不到,你花錢雇用管家來解決的煩惱正是這個遊戲導緻的!噢,這不禁讓我想起Allen Carr在《這書能讓你戒煙》裡的一句話:

吸煙者點燃香煙的目的是緩解尼古丁戒斷症狀,而這症狀正是由吸煙導緻的。

我把這種做法稱為"尼古丁解決方案":

你現在為人們解決的問題,正是你當初為他們種下的問題。

為了打破人們的心理防線,"尼古丁解決方案"通常會和"免費政策"結合使用,雖然人們通常不會認為免費的東西是什麼好東西,但免費這個特性很容易讓人們産生"不高興可以扔掉"的想法,這種派生出來的"零成本自由"恰恰就是讓人們上當的誘餌。噢,感覺我們像在探讨魔鬼的手段,内心似乎多少有些抗拒,哈哈,這其實是因為社會文化讓我們有了先入為主的觀念,正如李子勳在《幸福從心開始》裡說的:

物質存在的本身沒有對錯的,但人類社會的有序存在需要秩序,是以對錯就被發明出來。

我本人并不吸煙,我看《這書能讓你戒煙》是想了解"戒瘾原理"和"成瘾機制",前者可以用來打破舊有規則,後者則可以用來建立新的規則,當然,我主要想知道"戒瘾原理"是否适用于其它成瘾行為。

最後……

      如果你足夠細心,或許你會發現,在這個系列文章裡,我從未使用Trombone來稱呼這個應用程式,這是故意的,因為我想把這寶貴的第一次留給此刻,之是以取名Trombone是為了紀念我和一個人的關系,而這個人是玩長号的。

      和那些WM高手相比,我隻是一個接觸WM開發還不到半年的初學者,在這個過程裡,我學到很多東西,也得到很多樂趣,我希望這些文字能對其他WM初學者有所幫助,當然,如果WM高手也能有所得益就更好了。

      嗯,我知道你想說什麼,源代碼是吧,我已經把它放在Codeplex上了,單擊下面連接配接就能找到了:

  • http://trombone.codeplex.com/

那麼,下一季玩點啥呢?噓,薩斯頓三原則第一條:

魔術表演之前絕對不透漏接下來的表演内容。

繼續閱讀