C# LPC / 本地程序呼叫,
雖然進程通訊技術有很多類型,如 “具名管道、匿名管道、串口通訊、MSAA、
記憶體共用、檔案對應、通訊端、資料報、訊息佇列、Remoting、WCF、ASM”,
LPC(Local Procedure Call)是一種進程通訊技術、同時又是一種跨域控制技術
類似於RPC(Remote Procedure Call)在.NET正好提供該功能支援,不過RPC與
WCF對我們C/S開發人員而言並不是什麼值得讚揚的技術,首先WCF是HTTP協議
通訊,底層Socket / TCP可以理解是RPC的擴充,WCF倒是有一種修改App.Config
中BaseAddress為Net.Tcp://LocalHost:Port過而以TCP通訊 我不知道這有何意義,
即使RPC支援IPC與TCP可以讓跨網域作業變得更加快捷、但C/S軟體多為單機版
如果是跨電腦操作,RPC / IPC會很好 但本人對WCF該技術沒有太多好感可言、
下面是一張LPC跨域的:
假設A.exe通過LPC映射一個對象,B.exe通過LPC擷取到A.exe映射的對象
然後B.exe直接開始操作 B.exe調用跨域得到A.exe中的對象中函數會在A.exe
中處理 處理完畢後在傳送結果到B.exe如此一個固定的流程
世界上沒有徹底完美的跨網域作業技術,但目前而言已經足夠 莫要奢求太多
較為複雜一些,不過可以闡述下面的代碼 主要是為軟體設計
的一個LPC應用過程示意(娛樂非商業) 代碼按照修改部分命名形成的
為一個正在被調試的Themyth Chrome應用,仔細看工作管理員你否會很好奇
為什麼vshost32-clr2.exe記憶體消耗很少,該軟體在設計時是把WebBrowser拆分為
獨體,如Google Chrome && Internet Explorer 10
共分兩部分一部分為WebBrowser服務進程(後台) 另一個部分為WebBrowser管理
進程(前台) 不過代碼編寫“後台”與“前台”整合在一個執行檔案內 已經成為共識
自己看看優秀的多標籤瀏覽器
不過.Net WebBrowser還是很人性化的,把大量坑爹的代碼封裝 如正常情況需要
為WebBrowser自訂JScript Extern功能支援還有WebBrowser去掉邊框 必須為
WebBrowser掛接IDocHostUIHandler介面,原先特地做過一次 呵呵 我差點沒哭
預設平面風格且WebBrowser.ObjectForScripting = 自訂JScript Extern好方便
好吧 已經扯的太過遙遠
MSAA / LPC有一個缺點在於只適用於表單程式,起初它主要是協助殘疾及弱小
的代碼因為是擷取本進程通過LPC映射的WebRemoteObject時,擷取後我們
可以直接轉換為WebRemoteObject,然後直接操作但是在本進程內只是測試LPC
通過Mutex(互斥體)檢查是否已運行,如果App沒有運行那麼運行MainForm
已經看到MainForm是通過LPC映射對象的地方,如果App正在運行那麼
使用FindWindow尋找標題為MainForm的視窗控制代碼,得到視窗控制代碼後通過
LPCForm.GetRemoteObject / RemoteContext.GetRemoteObject 擷取該窗
口相關的對象,但是我們看到類型是COM對象 不再是WebRemoteObject
重點:如果系統內沒有註冊你編寫需要跨域的物件類型 那麼另一個進程擷取
後無法轉換類與介面,很簡單的一個道理B進程並不知道A進程中映射的對象
具體是什麼類型,所以它把對象看成一個IDispatch / IUnknown(是不是感到
回到C++的時代)呵呵,如果你編寫一個獨立的COM庫並註冊在系統中那麼
B進程就知道是什麼類型、但是可以不那麼做 要擷取它的值怎麼做?反射
我特意編寫一個CComObject類主要擴充對該問題的解決、但是我建議大家
編寫一個Wrapper類,可以理解為相互調用協議
有一個WebRemoteObjectWrapper類,上面提到過相互調用協議
它並不難寫,相反它很簡單忽略繁瑣大量操作 而且不需要向系統註冊
LPC應用很容易,不需要編寫過多的代碼 也可以實現需要的功能、
不過需要說明的一點是,在調試該項目時 應先編譯調試 然後再到編譯
後目錄下找到項目執行檔案 然後在運行一次 便可以看到跨網域作業效果
樣本源碼:http://share.weiyun.com/3102c171964c0693cf0f3a2f9906f53b
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。