• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            Dict.CN 在線詞典, 英語學(xué)習(xí), 在線翻譯

            學(xué)海苦作舟,書山勤為徑

            留下點(diǎn)回憶

            常用鏈接

            統(tǒng)計(jì)

            積分與排名

            Denoise

            English study

            Web技術(shù)

            數(shù)據(jù)壓縮

            一些連接

            最新評(píng)論

            進(jìn)程間通訊-WriteProcessMemory和ReadProcessMemory

            最近在寫個(gè)程序的時(shí)候需要在進(jìn)程間通訊,具體需求是這樣。

            1.?????? 主要有兩個(gè)進(jìn)程:一個(gè)進(jìn)程作為被請(qǐng)求進(jìn)程,我們稱為 SERVER 進(jìn)程;另一個(gè)進(jìn)程是請(qǐng)求進(jìn)程,稱為 CLIENG 進(jìn)程。

            2.?????? SERVER 進(jìn)程提供一些服務(wù),其完成計(jì)算功能;而 CLIENT 進(jìn)程需要在它執(zhí)行完計(jì)算之后將結(jié)果取會(huì)。

            ?

            由于計(jì)算結(jié)果可能是一個(gè)結(jié)構(gòu),也可能是一個(gè)復(fù)雜的數(shù)據(jù),所以通過消息來在進(jìn)程傳遞信息是有限的。另一方面一般是單方向的通訊,實(shí)際上這里的需求有一個(gè)雙向性,看下圖:

            ProcessComm.JPG


            這里兩個(gè)進(jìn)程都可以有自己的窗口,因此實(shí)際上我們可以通過消息來通知對(duì)方。但仔細(xì)一想,請(qǐng)求服務(wù)通過windows消息是沒有問題的,通知結(jié)果通過消息是不妥當(dāng)?shù)模瑢?shí)際上我們需要在請(qǐng)求服務(wù)完以后立即得到執(zhí)行結(jié)果,而使用windows消息可能有時(shí)間上的問題,而且同步非常麻煩。

            想要的結(jié)果是在 CLIENT 請(qǐng)求服務(wù)以后立即得到返回結(jié)果,但我們可以改變一下思路就容易多了:結(jié)果不是有 SERVER 返回,而由 CLIENG 自己去獲取。這樣,我們可以在請(qǐng)求消息的時(shí)候使用 SendMessage 來發(fā)送這個(gè)請(qǐng)求。這是必須的, SendMessage 發(fā)送消息是同步的方式,必須等到消息處理完畢之后才返回,而這正是我們想要的結(jié)果。那么 CLIENT 怎么樣才能獲得 SERVER 進(jìn)程的結(jié)果來。

            我們知道, WINDOWS 下每個(gè)進(jìn)程都有自己的地址空間,一般情況下一個(gè)進(jìn)程訪問你一個(gè)進(jìn)程的地址是不正確的,最簡單的是提示該地址無效,程序崩潰。當(dāng)然還是有很多中方式來讀取對(duì)方進(jìn)程的地址空間上的數(shù)據(jù)。

            1.? 可以做一個(gè) DLL ,利用注入 DLL 的方式,來將該 DLL 注入到遠(yuǎn)程進(jìn)程的地址空間上,然后通過 DLL API 來讀取。這個(gè)方式有點(diǎn)麻煩,還必須寫一個(gè) DLL ,還要注入 DLL

            2.? 使用 WriteProcessMemory ReadProcessMemory 來讀寫遠(yuǎn)程進(jìn)程的內(nèi)存。這種方式相對(duì)比較簡單,其有一個(gè)參數(shù)遠(yuǎn)程進(jìn)程的 HANDLE 指示你需要讀寫哪個(gè)進(jìn)程的內(nèi)存。當(dāng)然,使用這兩個(gè)函數(shù)是需要遠(yuǎn)程進(jìn)程的地址空間的,這個(gè)地址是通過 VirtualAllocEx 來分配的,其通過 VirtualFreeEx 來釋放。這兩個(gè) API 也有一個(gè)進(jìn)程句柄參數(shù)。

            有人問,為什么不使用 WM_COPYDATA 來傳遞大塊數(shù)據(jù)?好,該消息是可以傳遞大塊數(shù)據(jù),但我們的應(yīng)用中需要消息的雙向,所以這里使用 WM_COPYDATA 是不合適的。

            ?

            下面我們看一下第 2 種方法的具體步驟:

            1.? 找到對(duì)方進(jìn)程的窗口。

            2.? 找到他的進(jìn)程 ID

            3.? 使用 PROCESS_VM_OPERATION| PROCESS_VM_WRITE|PROCESS_VM_READ 標(biāo)志來打開該進(jìn)程,得到該繼承的 HANDLE

            4.? 使用 VirtualAllocEx 來在該進(jìn)程上分配適當(dāng)大小的內(nèi)存,得到一個(gè)地址,這個(gè)地址是遠(yuǎn)程進(jìn)程的,通過不同的方式來修改該地址上的值是無效的。

            5.? 如果需要傳遞一些參數(shù)到遠(yuǎn)程進(jìn)程,我們可以在該內(nèi)存上寫一些內(nèi)容,通過 WriteProcessMemory 來完成

            6.? 使用 SendMessage 來發(fā)送請(qǐng)求服務(wù)消息,同時(shí)將上面分配的內(nèi)存地址作為參數(shù)傳遞給遠(yuǎn)程進(jìn)程。

            7.? 遠(yuǎn)程進(jìn)程得到指定消息后處理該消息,取得參數(shù),計(jì)算結(jié)果,將結(jié)果寫到指定的地址。由于這個(gè)地址是遠(yuǎn)程進(jìn)程自己的地址空間,其操作這塊內(nèi)存的方法沒有什么特別之處。

            8.? SendMessage 消息返回, CLIENT 知道后,從上面的內(nèi)存地址中讀取返回結(jié)果;這里必須使用 ReadProcessMemory 來讀取。好了,整個(gè)過程結(jié)束。

            9.? 調(diào)用 VritualFreeEx 將上面的內(nèi)存釋放。

            這里需要強(qiáng)調(diào)兩點(diǎn):

            1.? 打開進(jìn)程的時(shí)候必須設(shè)置對(duì)虛擬內(nèi)存可操作、可寫、可讀,如果只是可寫,那么 ReadProcessMemory 將讀取不正確。

            2.? 必須釋放該內(nèi)存。

            ?

            下面是部分程序:

            CLIENT 程序:

            #define ??? WM_COMPAREIMAGE WM_USER +100

            ?

            void CTestCompareDlg::OnBnClickedButton1()

            {

            ??? HANDLE hProcess = NULL;

            ??? DWORD dwProcessId = 0;

            ??? HWND hServerWnd = ::FindWindow(NULL,"CompareServer");

            ??? if(hServerWnd == NULL)

            ??? {

            ?????? //Need create the process

            ?????? return ;

            ??? }

            ??? ::GetWindowThreadProcessId(hServerWnd,&dwProcessId);

            ??? hProcess = OpenProcess(PROCESS_VM_OPERATION|

            ?????? PROCESS_VM_WRITE|PROCESS_VM_READ,FALSE,dwProcessId);

            ??? if(hProcess == NULL) return ;

            ?

            ??? MyInfo * pMyInfo = NULL;

            ?

            ??? pMyInfo = (MyInfo *)VirtualAllocEx(hProcess,NULL,

            ?????? sizeof(MyInfo),MEM_COMMIT,PAGE_READWRITE);

            ?

            ??? if(pMyInfo == NULL) return ;

            ??? MyInfo myInfo;

            ??? myInfo.blue = 20.01;

            ??? myInfo.red = 3333;

            ?

            ??? WriteProcessMemory(hProcess,pMyInfo,&myInfo,sizeof(MyInfo),NULL);

            ?

            ??? ::SendMessage(hServerWnd,WM_COMPAREIMAGE,sizeof(MyInfo),(LPARAM)pMyInfo);

            ???

            ??? DWORD dwRead = 0;

            ??? MyInfo myInfo2;

            ??? BOOL bRet = ::ReadProcessMemory(hProcess,pMyInfo,&myInfo2,sizeof(MyInfo),&dwRead);

            ?

            ??? dwRead = GetLastError();

            ??? m_log.Format("red =%.2f,blue=%.2f",myInfo2.blue,myInfo2.red);

            ??? TRACE(m_log);

            ??? VirtualFreeEx(hProcess,pMyInfo,0,MEM_RELEASE);

            ??? UpdateData(FALSE);

            }

            ?

            SERVER 程序:

            LRESULT??? CMyWindow::OnCompareImage(HWND hWnd,WPARAM wParam,LPARAM lParam)

            {

            ??? if(wParam <sizeof(MyInfo)) return -1;

            ??? MyInfo * pMyInfo = (MyInfo *)lParam;

            ?

            ??? sprintf(m_strLog,"client:red=%.2f,blue=%.2f",pMyInfo->red,pMyInfo->blue);

            ??? ::TextOut(GetDC(hWnd),0,50,m_strLog,strlen(m_strLog));

            ??? pMyInfo->blue = 1.0;

            ??? pMyInfo->red = 2.0;

            ??? return 0;

            }

            源碼下載:CompareServer.zip

            posted on 2006-04-20 21:54 笨笨 閱讀(9557) 評(píng)論(6)  編輯 收藏 引用

            評(píng)論

            # re: 進(jìn)程間通訊-WriteProcessMemory和ReadProcessMemory 2006-04-21 09:11 小明

            雖然是可行的,更好的方法是使用Pipe

            //example from msdn
            while (1)
            {
            // Read client requests from the pipe.
            fSuccess = ReadFile(
            hPipe, // handle to pipe
            chRequest, // buffer to receive data
            BUFSIZE*sizeof(TCHAR), // size of buffer
            &cbBytesRead, // number of bytes read
            NULL); // not overlapped I/O

            if (! fSuccess || cbBytesRead == 0)
            break;
            GetAnswerToRequest(chRequest, chReply, &cbReplyBytes);

            // Write the reply to the pipe.
            fSuccess = WriteFile(
            hPipe, // handle to pipe
            chReply, // buffer to write from
            cbReplyBytes, // number of bytes to write
            &cbWritten, // number of bytes written
            NULL); // not overlapped I/O

            if (! fSuccess || cbReplyBytes != cbWritten) break;
            }
              回復(fù)  更多評(píng)論   

            # re: 進(jìn)程間通訊-WriteProcessMemory和ReadProcessMemory 2006-04-21 09:20 christanxw

            內(nèi)存映射文件才是進(jìn)程間共享的根本!  回復(fù)  更多評(píng)論   

            # re: 進(jìn)程間通訊-WriteProcessMemory和ReadProcessMemory 2007-01-26 14:00 yesry

            厲害  回復(fù)  更多評(píng)論   

            # re: 進(jìn)程間通訊-WriteProcessMemory和ReadProcessMemory 2008-10-17 09:59 coolicelee

            可以在DLL終定義一個(gè)Share段,大家通過調(diào)用DLL訪問,比如在代碼中定義
            #pragma data_seg("SharedSCT")
            DWORD g_dwValue = 0;
            #pragma data_seg()
            然后在def中定義
            SECTIONS
            SharedSCT Read Write Shared  回復(fù)  更多評(píng)論   

            # re: 進(jìn)程間通訊-WriteProcessMemory和ReadProcessMemory 2009-04-01 16:41 loskiller

            請(qǐng)問,創(chuàng)建出來的pMyInfo 要如何釋放?  回復(fù)  更多評(píng)論   

            # re: 進(jìn)程間通訊-WriteProcessMemory和ReadProcessMemory 2010-08-15 21:33 fifi

            WM_COPYDATA 也可實(shí)現(xiàn)雙向的,需要變通一下!  回復(fù)  更多評(píng)論   


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            久久国产精品成人影院| 久久亚洲AV无码精品色午夜 | 成人免费网站久久久| 国内精品久久久久久久久| 国产欧美久久久精品影院| 国内精品久久国产大陆| 国产精品成人无码久久久久久| 国产亚洲精品久久久久秋霞| 精品人妻伦九区久久AAA片69 | 久久久久亚洲AV无码永不| 亚洲精品无码久久毛片| 久久久久久av无码免费看大片| 久久香蕉国产线看观看99| 国产精品99久久免费观看| 波多野结衣久久一区二区| 精品久久久久久国产| 国产精品久久久久AV福利动漫 | 精品欧美一区二区三区久久久| 国产精品久久久久国产A级| 69国产成人综合久久精品| 色偷偷久久一区二区三区| 久久99中文字幕久久| 手机看片久久高清国产日韩| 久久久久久午夜成人影院| 久久99久久无码毛片一区二区| 欧美激情精品久久久久久| 亚洲欧洲中文日韩久久AV乱码| 久久久久人妻精品一区二区三区| 91精品国产91久久久久福利| 久久精品国产亚洲一区二区三区| 91久久精一区二区三区大全| 久久精品成人| 久久精品亚洲福利| 久久久久亚洲Av无码专| 久久久这里有精品| 国产一区二区精品久久岳| 日韩精品久久久久久久电影蜜臀| 一本色道久久88精品综合| 2021国产精品午夜久久| 91麻豆国产精品91久久久| 国内精品九九久久精品|