1. 程式人生 > >首款WindowsPhone 7 PC端實時截圖工具誕生攻堅實錄(一)

首款WindowsPhone 7 PC端實時截圖工具誕生攻堅實錄(一)

這是首款WindowsPhone 7 PC端實時截圖工具,能夠實時顯示Windows Phone真機中的介面!
演示GIF動畫如下:


演示視訊如下:

1、首先把手機連線到電腦上,並且啟動Zune,將電腦和手機設定為Connected狀態。
2、ItcastWPDevPC20110620.zip 是PC端程式,啟動ItcastWPDev.exe,設定監聽埠後點擊【Start】啟動監聽。
3、WP7ScreenMonitorAgent.xap是手機端程式。安裝後啟動“ScreenMonitor”,設定伺服器IP和埠後點擊【Start】啟動手機端監聽即可。如果要退出程式進入Tile主頁面或者進入別的程式,那麼需要按Home鍵,也就是Windows徽標鍵來回到Tile主頁面,不要按後退鍵退出程式,否則監聽程序會退出。

        下面開始正題,講解這個工具的開發過程和心得體會。這麼多年沒熬過夜了,這次我連續四天熬夜到3點多終於搞出來了這款工具,遂寫下戰鬥日記。PS:不要熬夜,真的傷身體。


一、有需求才能有產品——“學生說:要有是實時截圖工具!所以就有了截圖工具。”
        最近在備課傳智播客.Net培訓班的Windows Phone 7(WP7)的課程內容,雖然說通過模擬器基本能夠讓學生理解Windows Phone手機,不過如果能讓學生看到真機那感覺還是不一樣的。如何把Windows Phone真機的螢幕展示給講臺下的學生看就成了必須解決的問題,曾經想著用電腦攝像頭照手機的螢幕,但是反光問題很難解決,而且手在操作觸控式螢幕的時候就會遮擋螢幕,因此需要一款通過程式來擷取真機螢幕顯示到PC上的工具。

二、解決後臺截圖問題——穩紮穩打
        “不要重複造輪子”,我先到網上搜索是否有了類似的工具,網上的資料都是關於擷取程式截圖的,我想要一個也能擷取手機中其他的程式介面的工具。最終找到一款牛人fiinix開發的“CSharp DllImport”,這個工具中提供了後臺截圖的功能,開啟程式以後進入到要截圖的介面按下拍照鍵就可以將當前介面的截圖儲存到MediaLibrary中,就是它了!


        不要小看這款工具,熟悉Windows Phone的開發人員看到它絕對有“它打開了通向Windows Phone未知領域的大門”,為什麼這麼說呢?首先看“後臺”功能,眾所周知,在Mango之前WP7是不支援多工的,因此一旦離開程式進入別的程式,那麼當前的程式就會被結束掉了。“CSharp DllImport”使用的是網上流傳的

《修改登錄檔讓WP7支援多工》的方法來避免離開程式比較程式被結束的問題。“CSharp DllImport”中啟動一個無限迴圈的後臺執行緒,不斷檢測手機的按鍵狀態,如果使用者按下了拍照鍵,則會自動進行系統截圖。問題又來了,Windows Phone中只能對本程式的介面進行截圖,是沒有提供全屏截圖的功能,對Windows Mobile、Windows CE的朋友可能會說“那呼叫GDI來截圖不就行了嗎?”,不幸的是,Windows Phone中不支援PInvoke機制的,也就是無法編寫呼叫GDI等win32 dll中的函式的程式碼,更不能呼叫自己用C/C++寫的dll。

        “Windows Phone中不支援PInvoke機制”這句話只是給你我這等菜鳥聽的,牛人從來不相信。有牛人發現了《在Windows Phone中呼叫win32 dll的方法》,原理就是微軟的Microsoft.Phone.InteropServices.dll中的ComBridge類提供了RegisterComDll方法用來註冊一個Com元件到WP7系統中,這樣將Native程式碼寫成一個Com元件,然後通過RegisterComDll註冊到系統中即可。神奇的大門打開了!!!

        Windows Phone底層仍然是Windows CE,可以把Windows Phone看成Windows CE上執行的一個大軟體,就像當年的Windows 3.1是DOS上執行的一個軟體一樣,因此我們就可以用支援Windows CE開發的平臺開發出Com元件,可以呼叫任何的Windows CE的SDK,然後放到Windows Phone中去執行。


        使用ComBridge呼叫VC編寫的Dll的幾個關鍵點,這塊開發要涉及到Com元件的開發以及Interop的知識,這塊知識不是這篇文章能覆蓋的,因此如果您不熟悉Com這個.Net的老祖宗,那麼可以不用看,也不影響你對於整體架構的理解。如果你需要熟練下面的每項技術,歡迎你來傳智播客.Net培訓班來學,我手把手的教你。

1)在VC中建立一個Com專案。注意如果要執行在HTC等Arm CPU的真機上時,需要構建ARM平臺的二進位制程式碼,如果要在Windows Phone7模擬器上執行的時候則需要構建為X86的平臺,因為XDE是X86的CPU。
把Com元件生成的dll每次修改Com元件並且編譯通過後都要拷到WindowsPhone專案中。為方便除錯,建議將Com專案的輸出路徑指向Windows Phone專案,這樣避免了把生成的dll拷來拷去的麻煩。

2)新增WMAppManifest.xml 到Windows Phone專案根目錄下內容為:
<?xml version="1.0" encoding="utf-8" ?>
<Interop>
</Interop>

3)修改Windows Phone專案的WMAppManifest.xml檔案,在Capabilities節點下增加
<Capability Name="ID_CAP_INTEROPSERVICES" />
也就是給程式INTEROP的能力。

4)在使用元件之前(比如程式啟動的時候、類的Static初始化中)呼叫RegisterComDll方法用來註冊Com元件
例子:ComBridge.RegisterComDll("Network.dll", new Guid("0111B877-9EE5-45ba-800E-CF324B5552C7"));
Network.dll 為Com元件的dll檔名,"0111B877-9EE5-45ba-800E-CF324B5552C7"為元件實現類的Guid。

5)在Windows Phone中宣告對應的實現類和介面,使用ComImport標記類和介面,例如:
    [ComImport, Guid("0111B877-9EE5-45ba-800E-CF324B5552C7"),
    ClassInterface(ClassInterfaceType.None)]
    internal class NetworkClass
    {
    }
   
    [ComImport, Guid("25CC9D0F-CA11-4DED-8019-BC7C20CEE5D3"),
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface INetSockets
    {
        [PreserveSig]
        int HttpPost(string remoteServer, int remotePort, string path, IntPtr buffer, int len);
    }
    然後INetSockets socks = new NetworkClass() as INetSockets;就可以拿到元件的例項然後呼叫Com元件中的方法了!
   
   
    “CSharp DllImport”中使用的是CreateCompatibleDC、BitBlt等GDI方法來進行螢幕擷取的,沒什麼特別的,不再詳述。    現在已經有很多基於這個機制的WP7程式了,比如登錄檔編輯器RegistryEditor、TouchXPlorer、Yaaf.Wp7.AdvancedExplorer等。“CSharp DllImport”本身已經提供了大量的底層操作的API,包括獲取電池狀態、系統程式導航控制、獲得系統按鍵狀態、訪問系統檔案、訪問登錄檔、直接撥號、操作貼上板、程序控制等很多方法,感興趣的直接開啟CSharp - DllImport.dll的類結構就都明白了,不再詳細的講。注意使用這種方法呼叫Native程式碼是無法通過Marketplace稽核的,所以這樣的工具只能在越獄的機器上直接部署Xap的方式安裝。


    現在Windows Phone還沒有系統級別的中文輸入法,我猜測也許可以將Windows CE上的中文輸入法通過這樣的方法移植到Windows Phone上,這樣可以解決Mango之前大家用不了輸入法的問題,有高人如果想做這項好事,我非常非常以及非常願意提供幫助。

     後續講解在後臺程式中上傳資料的方法以及一些程式優化手段。未完待續。。。

如鵬網.Net培訓班正在報名,有網路的地方就可以參加如鵬網的學習,學完就能高薪就業,點選此處瞭解

三年前只要懂“三層架構”就可以說“精通分層架構”;現在則需要懂IOC(AutoFac等)、CodeFirst、lambda、DTO等才值錢;

三年前只要會SQLServer就可以說自己“精通資料庫開發”;現在則需還需要掌握MySQL等開源資料庫才能說是“.Net開源”時代的程式設計師;

三年前只要會進行使用者上傳內容的安全性處理即可;現在則需要熟悉雲端儲存、CDN等才能在雲端計算時代遊刃有餘;

三年前只要掌握Lucene.Net就會說自己“熟悉站內搜尋引擎開發”;現在大家都用ElasticSearch了,你還用Lucene.Net就太老土了;

三年前發郵件還是用SmtpClient;現在做大型網站發郵件必須用雲郵件引擎;

三年前快取就是Context.Cache;現在則是Redis、Memcached的天下;

如鵬網再次引領.Net社群技術潮流!點選此處瞭解如鵬網.Net最新課程