專利名稱:一種準(zhǔn)確控制外部程序的方法
技術(shù)領(lǐng)域:
本發(fā)明涉及計算機軟件技術(shù),特別是涉及在Unix,Linux下方便快捷地準(zhǔn)確控制外部程序的方法。
背景技術(shù):
在現(xiàn)實中經(jīng)常會出現(xiàn)一個程序控制另一個程序的需求。比如windows下的遙控器應(yīng)用軟件??刂瞥绦蚪邮者b控器的紅外信號,將其轉(zhuǎn)換為相應(yīng)的控制信息,然后再控制其它的外部程序。這樣的過程很象一種通訊機制,也是一種進程間通訊機制。那么要如何實現(xiàn)這一點呢?在windows下有多種實現(xiàn)方法。以下是一些常用的方法。
1、共享在硬盤上建立一個文件,一個應(yīng)用程序往該文件里寫數(shù)據(jù)(可以不關(guān)閉文件,但必須刷新緩沖區(qū)),另一個應(yīng)用程序以共享方式打開這個文件并讀取其中的內(nèi)容,這便是最簡單的一種數(shù)據(jù)交換方式。對于網(wǎng)絡(luò)用戶而言,只要兩臺終端上安裝的都是Win311 For Workgroup或Windows 95(或NT),則只要設(shè)置一下目錄共享,映射成網(wǎng)絡(luò)驅(qū)動器,同樣可以簡單地實現(xiàn)數(shù)據(jù)交換。但它的缺點也是顯而易見的只能采取輪詢的方式獲得最新數(shù)據(jù),因此效率低下,網(wǎng)絡(luò)映射的驅(qū)動器絕對不能變動或取消,可靠性差,所以這是一種“低級”的通訊方式。
2、DDE每個Windows程序員都不會對DDE(動態(tài)數(shù)據(jù)交換)感到陌生,它是最早的基于Windows的數(shù)據(jù)交換方法,有三種方式可供選擇冷連接、溫連接和熱連接。一般都是由客戶端向服務(wù)器端發(fā)出連接申請,并且必須指明服務(wù)器端的名字和標(biāo)題。在連接建立后,數(shù)據(jù)可以雙向流動。典型的例子如抓圖軟件SnagIt,它提供了DDE接口,能夠讓其它應(yīng)用程序來控制它。DDE是完全向后兼容的,從16位平臺轉(zhuǎn)到32位,源代碼幾乎不用修改。
DDE還有網(wǎng)絡(luò)功能。使用過Win311 For Workgroup的人大概都還記得,它自帶一個非常吸引人的小程序“Chat”,能使兩臺計算機通過網(wǎng)絡(luò)實時交談,這在當(dāng)時幾乎是一項創(chuàng)舉??墒呛苌儆腥酥馈癈hat”使用的實際上是一種特殊的DDE,即NetDDE。它的基本工作原理仍然是DDE,但它能使一臺計算機向在同一個網(wǎng)絡(luò)中的另一臺終端發(fā)消息,而不像普通DDE只能局限在同一臺機器上。與其它的數(shù)據(jù)交換方式相比,DDE已不夠先進,而且Microsoft也不再積極支持DDE,所以它的前景不被看好。
3、WM_COPYDATAWindows消息WM_COPYDATA功能強大,知之者卻甚少。它的確切定義是一個應(yīng)用程序向另一個應(yīng)用程序傳遞數(shù)據(jù)時所發(fā)出的消息。眾所周知,Windows在很大程度上依賴于消息機制,那么為什么不把數(shù)據(jù)放在消息中一起發(fā)送出去呢?這樣,只要調(diào)用SendMessage(),以對方窗體的句柄作為第一個參數(shù),以含有指向?qū)嶋H數(shù)據(jù)的指針結(jié)構(gòu)的地址作為第二個參數(shù),就可以把整個數(shù)據(jù)塊當(dāng)作消息發(fā)向另一個應(yīng)用程序。也許有的程序員會說,一個自定義的消息同樣可以完成這樣的工作。他只說對了一半,自定義消息的確可以發(fā)送到其它的應(yīng)用程序上去,但其原始數(shù)據(jù)所在的內(nèi)存區(qū)只有在發(fā)送過程中才是合法的,若在其它模塊中存取該內(nèi)存區(qū)就會導(dǎo)致“AccessViolation”。而使用WM_COPYDATA則不存在這個問題,因為Windows本身會替你處理這一切。深入鉆研下去,就會發(fā)現(xiàn)它其實是先創(chuàng)建了一個文件映射的對象,將發(fā)送方的原始數(shù)據(jù)先拷貝至映射文件,然后再在接收方對這個映射文件打開一個“視圖”。WM_COPYDATA的不足之處在于必須要有一個窗體來接收消息和數(shù)據(jù),缺乏靈活性,數(shù)據(jù)在使用之前先得拷貝到一個映射文件,造成資源浪費。
4、NetBIOS
從20世紀(jì)80年代開始,NetBIOS就是開發(fā)Client/Server類程序的標(biāo)準(zhǔn)接口。而當(dāng)時其它的解決方案幾乎都是從UNIX系統(tǒng)上發(fā)展而來的。當(dāng)然,對于今天的用戶而言,NetBIOS已不是唯一的選擇,他們可以從各種方案中擇優(yōu)選取。在Windows 95和NT平臺上,可以通過API函數(shù)Netbios()來調(diào)用NetBIOS功能。
NetBIOS兼容以下幾種低層協(xié)議NetBEUI協(xié)議(NBF)、NWLinkNetBIOS(NWNBlink)、NetBIOS over TCP/IP(NetBT)。NetBIOS的優(yōu)點是速度較快,缺點是可靠性較差。
5、標(biāo)準(zhǔn)的Sockets和WinSockSockets是15年前在UNIX系統(tǒng)上提出來的,一開始主要是用于本地通訊,但很快就應(yīng)用在Client/Server體系上了。它的內(nèi)核很簡單你可以將一個Socket看作是一個雙向的節(jié)點,一個應(yīng)用程序可以通過它先與另一個程序建立連接(建立在一個雙方都認(rèn)可的端上,以便于區(qū)分同時運行的幾個通訊線程),然后就可以彼此交換數(shù)據(jù)了。微軟公司在其基礎(chǔ)上創(chuàng)建了WinSock,專門用于Windows接口,與Socket完全兼容。近年來基于TCP/IP協(xié)議的網(wǎng)絡(luò)大行其道,Socket也隨之獲得了更加廣泛的應(yīng)用。
如今,Sockets已在Internet上獲得了最廣泛的應(yīng)用,主要是因為它的可移植性好Socket應(yīng)用程序無論在任何平臺間都能互相進行通訊(不管是PC機還是Macintosh,也不管是Windows平臺還是UNIX平臺)。而最新推出的WinSock2.0,已不僅僅只基于TCP/IP協(xié)議,還可基于其它幾種傳輸協(xié)議(如IPX)。Socket的缺陷是它工作在通訊的低層,所以實現(xiàn)起來較為復(fù)雜(如果是Win95或NT平臺,則不存在這個問題,微軟公司提供了相應(yīng)的控件)。但是,如果要在多個平臺間互相通訊,則Socket是不二之選。
6、Mailslot和PipeMailslot和Pipe有很多相同點,即都是高層的、基于內(nèi)存的通訊系統(tǒng)。Mailslot由Server端創(chuàng)建,代碼如下myMailslot=CreateMailslot(pSlotName,0,MAILSLOT_WAIT_FOREVER,NULL);然后,Client端就可以像打開文件一樣打開這個Mailslot,再通過API函數(shù)WriteFile()來將數(shù)據(jù)寫入到消息隊列中。
與此相類似,Pipe也是由Server端創(chuàng)建的,代碼如下pipe=CreateNamedPipe(pPipeName,PIPE_ACCESS_DUPLEX,PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE|PIPE_WAIT,PIPE_UNLIMITED_INSTANCES,BUFSIZE,BUFSIZE,20000,NULL);接著,Client端就可以通過一般的文件API讀寫數(shù)據(jù),代碼如下pipe=CreateFile(pPipeName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);success=WriteFile(pipe,pMessage,strlen(pMessage)+1,& bytesWritten,NULL);Pipe分兩種,即命名Pipe和匿名Pipe。匿名Pipe是以句柄而不是以名字來進行標(biāo)識的,因而也就限制了它只能在同一臺機器上通訊,而不能應(yīng)用于網(wǎng)絡(luò)。命名Pipe則提供了以名字來進行標(biāo)識,所以能在網(wǎng)絡(luò)上的其它任何地方打開它。需要注意的是命名Pipe只能在Win NT而不是Win 95上創(chuàng)建(即Server端),Client端則可以是任意平臺。
Pipe既可以單向通訊也可以雙向通訊,Mailslot則只能單向通訊。Client端可以發(fā)送消息給mailslot,但不能接收消息;如果你想要接收消息,則只能創(chuàng)建一個新的mailslot。但mailslot有一個很大的優(yōu)點它支持?jǐn)?shù)據(jù)廣播。也就是說,若Client端發(fā)送一條消息,則整個網(wǎng)絡(luò)中的同名對象都能收到。這是因為mailslot的名字的作用域只是在本臺機器上,所以可在不同機器上創(chuàng)建同名的mailslot,當(dāng)Client端發(fā)來消息時則每一臺機上的mailslot都得到了該消息的一份拷貝,并在本機上作出相應(yīng)的反應(yīng)。Mailslot的最大缺陷是不可靠,因為它的數(shù)據(jù)是以數(shù)據(jù)報格式來傳送的,網(wǎng)絡(luò)錯誤或負(fù)荷過重都會導(dǎo)致數(shù)據(jù)丟失。
Pipe雖然較為可靠,但它不能廣播。所以,如果不需要進行廣播,則Pipe是更好的選擇。選擇Mailslot,則要對此后遇到的麻煩有充分的準(zhǔn)備。
7、多剪貼板(Clipboard)Windows的剪貼板的出現(xiàn)就是為了實現(xiàn)應(yīng)用程序間的互相數(shù)據(jù)交換。Windows提供了一系列的API函數(shù)來讓應(yīng)用程序安全地打開剪貼板,讀寫其中的數(shù)據(jù)。
剪貼板的缺陷也是顯而易見的當(dāng)有新的數(shù)據(jù)放在剪貼板上時,則先前的數(shù)據(jù)就會被沖掉,而在Windows中用到剪貼板的時候又實在太多了,所以這種方式用于程序間的通訊顯然不夠安全。
8、COM和DCOM公共對象模式(COM)是一種協(xié)議,它建立了一個軟件模塊同另一個軟件模塊之間的連接,然后將其描述出來。當(dāng)這種連接建立起來之后,則兩個模塊之間就可以通過稱為“接口”的機制來進行通訊。COM可以用不同的語言(VB、VC、Delphi)進行編制,又能被其它語言編寫的程序所使用,并且不用理睬通訊雙方實際所處的位置(是在同一臺機上,還是在同一個網(wǎng)絡(luò)上的不同機上)。事實上,Internet上有大量的COM控件可供人們下載使用,其中有相當(dāng)一部分就是用于應(yīng)用程序間的相互通訊(甚至是Internet程序間的通訊),硬盤上能夠看到的大量的。ocx文件其實就是一種COM。
COM對象為外部調(diào)用提供了一個標(biāo)準(zhǔn)的界面,COM Client通過創(chuàng)建COMserver的一個實例獲得指針,轉(zhuǎn)向所需的函數(shù)定義處并執(zhí)行相應(yīng)的程序。講得通俗一點,也就是先正確定義好COM對象的屬性(Property),再執(zhí)行相應(yīng)的方法(Method)。
DCOM(分布式公共對象模式)是COM在網(wǎng)絡(luò)上的一種擴展,它通過把分布式對象間的通訊變成一個實體來實現(xiàn)通訊。
COM如今被微軟公司大力提倡,最著名的有OLE、ActiveX、DirectX和Win95、WinNT的外殼。由于微軟公司目前在軟件業(yè)處于霸主地位,所以COM很有可能成為將來的業(yè)界標(biāo)準(zhǔn),其前途也較為看好。但COM的龐大也會使一些經(jīng)驗豐富的程序員望而卻步,他們寧可自己多寫一些代碼以使整個程序更為簡潔、有效而不愿使用COM。
以上這些通訊方式都可以用來實現(xiàn)進程間的相互控制。但是都有一定的局限性。比如拿wi ndows消息傳送來舉例,為了說明這種方法,先來了解一下Windows消息驅(qū)動的工作機制。Windows的驅(qū)動方式是事件驅(qū)動,就是不由事件的順序來控制,而是由事件的發(fā)生來控制,所有的事件都是無序的,作為一個程序員,在編寫程序時,并不知道用戶先按哪個按紐,也不知道程序先觸發(fā)哪個消息。程序員的任務(wù)就是對正在開發(fā)的應(yīng)用程序要發(fā)出或要接收的消息進行排序和管理。事件驅(qū)動程序設(shè)計是密切圍繞消息的產(chǎn)生與處理而展開的,一條消息是關(guān)于發(fā)生的事件的消息。就是說當(dāng)你按下界面中的一個按鈕,選擇一個菜單,選擇一個列表的時候都是向windows發(fā)出了一個消息,windows會把這個消息正確分配給相應(yīng)的窗口函數(shù)。那么如果要達到控制其它程序的目的,只要能模擬出控制操作相應(yīng)的消息即可。但是這樣的做法的缺點是,對于每一個外部程序的控制必須先了解他的消息ID,雖然可以通過一些消息截獲的工具軟件獲得這一信息ID,但還是很麻煩,因為消息ID對于用戶是不可見的。這個問題造成程序很難做得通用。
發(fā)明內(nèi)容
本發(fā)明要解決的技術(shù)問題是提出一種準(zhǔn)確控制外部程序的方法,實現(xiàn)在Unix,Linux下方便快捷地控制外部程序。
本發(fā)明的實現(xiàn)方法如下步驟一、由控制程序的一個實例進程一,創(chuàng)建一個管道;步驟二、進程一用Linux的fork()函數(shù)創(chuàng)建一個子進程進程二;這個子進程會獲得進程一的數(shù)據(jù)空間,堆和棧的復(fù)制品;步驟三、在進程一和進程二之間創(chuàng)建兩個這樣的共享管道,以實現(xiàn)兩個進程間的雙向數(shù)據(jù)讀寫;步驟四、根據(jù)數(shù)據(jù)流的方向,分別關(guān)閉所述兩個進程共享管道的讀端或?qū)懚?,僅保留一個讀端和寫端;步驟五、將進程二的讀寫端連接到標(biāo)準(zhǔn)輸入輸出設(shè)備上;步驟六、加載需要控制的外部程序到子進程上,以實現(xiàn)控制程序?qū)ν獠砍绦虻耐耆刂啤?br>
采用本發(fā)明,能在Unix,Linux下方便快捷的實現(xiàn)控制外部程序。就可以大量的復(fù)用目前已有的程序,提高代碼復(fù)用性,節(jié)省開發(fā)時間,而不用重新編寫,節(jié)省了大量的開發(fā)成本;由于使用的是久經(jīng)考驗的程序,提高系統(tǒng)的可靠性。
圖1是本發(fā)明所述方法實現(xiàn)向外部程序發(fā)送命令的流程;圖2是本發(fā)明所述方法實現(xiàn)從外部程序讀出輸出結(jié)果的流程;圖3是管道的示意圖;圖4是創(chuàng)建子進程后的管道;圖5是從父進程到子進程的管道;圖6是從子進程到父進程的管道。
具體實施例方式
Unix,Linux下實現(xiàn)進程間通訊的方法主要有以下幾種,管道、消息隊列、信號量和共享存儲。由于管道是極少數(shù)可以在幾乎所有的Unix,Linux下都支持的通訊方式,所以用這種方法實現(xiàn)移植性很好。因此本發(fā)明采用管道來達到控制的目的。
本發(fā)明所述方法的基本步驟如下所述首先,控制程序的一個實例進程一創(chuàng)建一個管道。
進程一用Linux的fork()函數(shù)創(chuàng)建一個子進程進程二,由于這個子進程會獲得其父進程即進程一的數(shù)據(jù)空間,堆和棧的復(fù)制品,但管道本身不會被復(fù)制,因此這個子進程就可以和父進程進程一共享同一個管道。這個管道在每一個進程處都有一個讀端和寫端。根據(jù)數(shù)據(jù)流的方向分別關(guān)閉這兩個進程共享管道的讀端或?qū)懚恕?br>
僅留下一個讀端和寫端。這樣數(shù)據(jù)就可以從一個進程中的寫端流向另一個進程的讀端。當(dāng)需要向子進程寫數(shù)據(jù)的時候就關(guān)閉父進程的讀端和子進程的寫端。反之需要從子進程讀數(shù)據(jù)的時候就關(guān)閉父進程的寫端和子進程的讀端。
在父進程和子進程之間創(chuàng)建兩個這樣的共享管道,就可以實現(xiàn)兩個進程間的雙向數(shù)據(jù)讀寫。
連接子進程這邊的讀寫端到標(biāo)準(zhǔn)輸入輸出設(shè)備上,那么父進程流向子進程的數(shù)據(jù)在子進程看來就象從鍵盤輸入的一樣,而子進程輸出到標(biāo)準(zhǔn)輸出設(shè)備(一般是屏幕)的數(shù)據(jù),父進程可以完全的從管道的讀端獲取。
加載需要控制的外部程序到子進程上,就可以實現(xiàn)控制程序?qū)ν獠砍绦虻耐耆刂啤?br>
以下結(jié)合附圖以及實施例進一步說明本發(fā)明的基本思想。
如圖1所示,這是本發(fā)明所述方法的一個具體實施例,可以實現(xiàn)控制程序向外部程序發(fā)送命令。
第一步,創(chuàng)建父進程的一個管道;第二步,創(chuàng)建一個子進程,子進程會共享父進程的管道;第三步,關(guān)閉子進程的寫管道;第四步,將子進程的讀管道連接到標(biāo)準(zhǔn)輸入,利用這個子進程加載要控制的外部程序;第五步,關(guān)閉父進程的讀管道;第六步,從父進程的寫管道寫入命令,對于子進程程序來說就和接收鍵盤輸入一樣,從而實現(xiàn)控制外部程序的目的。
如圖2所示,這是本發(fā)明所述方法的另一個具體實施例,可以實現(xiàn)控制外部程序,即從外部程序讀出輸出結(jié)果。具體步驟如下第一步,創(chuàng)建一個管道;第二步,創(chuàng)建一個子進程,子進程會共享父進程的管道;第三步,關(guān)閉子進程的讀管道;第四步,將子進程的寫管道連接到標(biāo)準(zhǔn)輸出,利用這個子進程執(zhí)行要控制的外部程序;第五步,關(guān)閉父進程的寫管道;第六步,從父進程的讀管道讀入外部程序的輸出,父進程可以根據(jù)輸出來改變發(fā)送的命令流,從而實現(xiàn)控制外部程序的目的。
圖3是管道的示意圖,本發(fā)明中關(guān)于Linux下管道的實質(zhì)其實是駐留在內(nèi)核中的在內(nèi)部表示的一個合法索引節(jié)點,并且不在任何物理文件系統(tǒng)的范圍之內(nèi)。對管道的讀寫其實就是對內(nèi)核中這個節(jié)點的讀寫,利用這個特性,就可以實現(xiàn)控制外部程序。
圖4是創(chuàng)建子進程后的管道;可以看出,子進程會共享父進程創(chuàng)建的管道,每一個進程都分別有一個該管道的讀端口和一個寫端口。
圖5是從父進程到子進程的管道;如果關(guān)閉父進程對于這個管道的讀端口和子進程對于這個管道的寫端口,就可以形成數(shù)據(jù)只能從父進程流向子進程的管道。再把子進程的標(biāo)準(zhǔn)輸入端口連接到這個管道在子進程那邊的讀端口,那么從父端口寫入的數(shù)據(jù)就如同從鍵盤向子進程輸入數(shù)據(jù)一樣,從而實現(xiàn)模擬鍵盤對子進程的控制。
圖6是從子進程到父進程的管道。如果關(guān)閉父進程對于這個管道的寫端口和子進程對于這個管道的讀端口。就可以形成數(shù)據(jù)只能從子進程流向父進程的管道。再把子進程的標(biāo)準(zhǔn)輸出端口連接到這個管道在子進程那邊的寫端口,那么從子進程輸出到屏幕的數(shù)據(jù)就可以完全的從父進程的讀端口讀出,從而使父進程可以得到子進程的所有輸出反饋。
最后所應(yīng)說明的是以上實施例僅用以說明而非限制本發(fā)明的技術(shù)方案,盡管參照上述實施例對本發(fā)明進行了詳細說明,本領(lǐng)域的普通技術(shù)人員應(yīng)當(dāng)理解依然可以對本發(fā)明進行修改或者等同替換,而不脫離本發(fā)明的精神和范圍的任何修改或局部替換,其均應(yīng)涵蓋在本發(fā)明的權(quán)利要求范圍當(dāng)中。
權(quán)利要求
1.一種準(zhǔn)確控制外部程序的方法,其特征在于,包括如下步驟步驟一、由控制程序的一個實例進程一,創(chuàng)建一個管道;步驟二、進程一創(chuàng)建一個子進程進程二;步驟三、在進程一和進程二之間創(chuàng)建兩個這樣的共享管道,以實現(xiàn)兩個進程間的雙向數(shù)據(jù)讀寫;步驟四、根據(jù)數(shù)據(jù)流的方向,分別關(guān)閉所述兩個進程共享管道的讀端或?qū)懚?,僅保留一個讀端和寫端;步驟五、將進程二的讀寫端連接到標(biāo)準(zhǔn)輸入輸出設(shè)備上;步驟六、加載需要控制的外部程序到子進程上,以實現(xiàn)控制程序?qū)ν獠砍绦虻耐耆刂啤?br>
2.根據(jù)權(quán)利要求1所述的準(zhǔn)確控制外部程序的方法,其特征在于,向外部程序發(fā)送命令時,所述步驟四中包括關(guān)閉子進程的寫管道;將子進程的讀管道連接到標(biāo)準(zhǔn)輸入,利用這個子進程加載要控制的外部程序;關(guān)閉父進程的讀管道;從父進程的寫管道寫入命令。
3.根據(jù)權(quán)利要求1所述的準(zhǔn)確控制外部程序的方法,其特征在于,從外部程序讀出輸出結(jié)果時,所述步驟四中包括關(guān)閉子進程的讀管道;將子進程的寫管道連接到標(biāo)準(zhǔn)輸出,利用這個子進程執(zhí)行要控制的外部程序;關(guān)閉父進程的寫管道;從父進程的讀管道讀入外部程序的輸出。
4.根據(jù)權(quán)利要求1、2、3之一所述的準(zhǔn)確控制外部程序的方法,其特征在于,所述步驟二中進程一用Linux的fork()函數(shù)創(chuàng)建一個子進程進程二;所述子進程獲得進程一的數(shù)據(jù)空間,堆和棧的復(fù)制品。
5.根據(jù)權(quán)利要求1、2、3之一所述的準(zhǔn)確控制外部程序的方法,其特征在于,所述管道為駐留在內(nèi)核中的在內(nèi)部表示的一個合法索引節(jié)點。
全文摘要
本發(fā)明公開了一種準(zhǔn)確控制外部程序的方法,包括如下步驟步驟一、由控制程序的一個實例進程一,創(chuàng)建一個管道;步驟二、進程一創(chuàng)建一個子進程進程二;步驟三、在進程一和進程二之間創(chuàng)建兩個這樣的共享管道,以實現(xiàn)兩個進程間的雙向數(shù)據(jù)讀寫;步驟四、根據(jù)數(shù)據(jù)流的方向,分別關(guān)閉所述兩個進程共享管道的讀端或?qū)懚?,僅保留一個讀端和寫端;步驟五、將進程二的讀寫端連接到標(biāo)準(zhǔn)輸入輸出設(shè)備上;步驟六、加載需要控制的外部程序到子進程上,以實現(xiàn)控制程序?qū)ν獠砍绦虻耐耆刂?。采用本發(fā)明,能在Unix,Linux下方便快捷的實現(xiàn)控制外部程序,就可以大量的復(fù)用目前已有的程序,提高代碼復(fù)用性,節(jié)省開發(fā)時間,而不用重新編寫,節(jié)省了大量的開發(fā)成本。
文檔編號G06F9/52GK1516010SQ0310000
公開日2004年7月28日 申請日期2003年1月2日 優(yōu)先權(quán)日2003年1月2日
發(fā)明者邵蘇毅, 陸寬, 柯妍 申請人:聯(lián)想(北京)有限公司