• <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   管理


            久久青青草原精品国产不卡| 亚洲va久久久噜噜噜久久男同| 久久精品中文字幕久久| 亚洲国产综合久久天堂| 一本大道久久a久久精品综合| 日本加勒比久久精品| 青青草国产97免久久费观看| 亚洲国产另类久久久精品黑人 | 国产精品无码久久综合| 久久人人妻人人爽人人爽| 亚洲AV无码久久精品成人| 久久精品中文騷妇女内射| 999久久久无码国产精品| 亚洲伊人久久综合中文成人网| 亚洲精品无码久久久| 97精品国产91久久久久久| 伊人 久久 精品| 国产精品xxxx国产喷水亚洲国产精品无码久久一区| 国产99久久久国产精品小说| 看全色黄大色大片免费久久久| 久久人人爽人人爽人人片AV不| 久久久久精品国产亚洲AV无码| 日本精品久久久久久久久免费| 99久久er这里只有精品18| 欧美一区二区久久精品| 久久人妻少妇嫩草AV无码蜜桃 | 亚洲国产视频久久| 久久精品国产亚洲综合色| 欧美精品一区二区精品久久 | 久久夜色精品国产噜噜麻豆| 国产精品美女久久久网AV| 久久婷婷国产综合精品| 伊人久久大香线焦AV综合影院 | 国产精品久久久久影院色| 久久综合给合久久狠狠狠97色| 无码任你躁久久久久久| 久久久久久久综合日本| 精品久久久久成人码免费动漫| 欧美与黑人午夜性猛交久久久| 99久久精品免费看国产免费| 中文字幕一区二区三区久久网站 |