2013-03-15 21 views
2

我編寫了兩個使用C++的進程。一個是我的控制檯應用程序使用CreateProcess API調用的GUI過程。我需要將文本從GUI應用程序(子)傳遞到控制檯應用程序(父級)。文本的數量可以是任意的 - 從幾行到文本的KB。從兒童GUI進程向控制檯父母發送文本的最簡單方法是什麼?

最簡單的方法是什麼?

PS。我可以訪問這兩個進程的源代碼。

+0

[pipes]怎麼樣(http://msdn.microsoft.com/en-us/library/windows/desktop/aa365780%28v=vs.85%29.aspx)? – 2013-03-15 07:13:52

+0

Ooph。我在尋找一些簡單的東西......但是,謝謝,我也想到了它。 – ahmd0 2013-03-15 07:15:34

+1

另外,如果我沒有記錯的話,你可以告訴'CreateProcess'使用特定的文件句柄來用於新進程的'stdin' /'stdout'。您可以創建一個[匿名管道](http://msdn.microsoft.com/en-us/library/windows/desktop/aa365139%28v=vs.85%29.aspx)並將寫入句柄設置爲新的進程'stdout',那麼新進程只需寫入'stdout'(就像'std :: cout << something'),父進程就可以讀取它。使用WIN32文件句柄並不難。 – 2013-03-15 07:26:03

回答

1

如果GUI應用程序只是真正的圖形化,那麼您並不真正使用標準輸出流(即std::cout)。這可以重新用於輸出到您的控制檯應用程序。

首先,你需要使用CreatePipe創建一個匿名管道:

HANDLE hPipeRead; 
HANDLE hPipeWrite; 

CreatePipe(&hPipeRead, &hPipeWrite, NULL, 0); 

現在你已經可以用來作爲一個正常的文件句柄句柄;一個讀取,另一個寫入。寫手柄應設置爲標準輸出爲新進程創建:

STARTUPINFO startupInfo = { 0 }; 
startupInfo.cb = sizeof(startupInfo); 
startupInfo.dwFlags = STARTF_USESTDHANDLES; 
startupInfo.hStdOutput = hPipeWrite; // Standard output of the new process 
             // is set to the write end of the pipe 

CreateProcess(
    lpApplicationName, 
    lpCommandLine, 
    NULL, 
    NULL, 
    FALSE, 
    0, 
    NULL, 
    NULL, 
    &startupInfo, // Use our startup information 
    &processInfo); 

現在,每當子進程需要寫入父,只需要使用標準輸出:

std::cout << "In child process, are you getting this parent?"; 

父使用ReadFile從管道的讀端閱讀:

char buffer[256]; 
DWORD bytesRead = 0; 

ReadFile(hPipeRead, buffer, sizeof(buffer), &bytesRead, NULL); 

注:我沒有做過WIN3 2在某些時間編程,所以在某些細節上可能會出錯。但希望能夠讓你開始。


有當然如果Inter Process Communications (IPC),包括(但不限於)插座,文件,共享存儲器等可用於

+0

非常感謝您的代碼示例。我會試試看。我唯一的問題是關於管道尺寸。當您創建它時,您將其大小指定爲0.理論上這是否意味着它可以包含儘可能多的數據?還是有一些默認限制? – ahmd0 2013-03-15 17:17:13

+0

@ ahmd0從'CreatePipe'的鏈接手冊頁面:「如果此參數爲零,則系統使用默認緩衝區大小。」到底什麼是默認的緩衝區大小我不知道,但除非你開始發送兆字節的數據應該沒有問題。 – 2013-03-15 18:19:36

+0

謝謝。我看到了文檔。 '除非你開始發送兆字節的數據,這應該沒有問題 - 這就是問題發生後的問題。 – ahmd0 2013-03-16 07:42:29

1

簡單的方法可能是讓孩子實際上是一個控制檯應用程序,即使它也創建窗口。

在這種情況下,您可以讓父母使用_popen產生孩子,孩子可以將輸出寫入正常的stdout/std::cout_popen返回一個FILE *,所以父母可以讀取孩子的輸出,就像它通常會讀取一個文件(好吧,通常對於C來說)。

+0

感謝您的建議。不幸的是,GUI應用程序涉及太多的代碼來改變它。實現上面提到的管道服務器/客戶端方法會更容易。 – ahmd0 2013-03-15 07:21:42

+0

沒有辦法通過某種基於線程的WM_COPYDATA消息發送該文本,是嗎? – ahmd0 2013-03-15 07:22:42

+0

@ ahmd0:將GUI應用程序轉換爲控制檯應用程序非常簡單:將啓動函數從「WinMain」重命名爲「main」。他們採取不同的參數,但您通常無視這些參數。你可以做WM_COPYDATA(使用PostThreadMessage),但它有點難看。另一種可能性是讓GUI應用程序爲父節點編寫調試消息('OutputDebugString')來攔截(父節點將充當調試器)。 – 2013-03-15 07:32:25

3

控制檯應用程序可以創建一個WinAPI窗口(不可見),以便它可以接收消息(從Delphi中的AllocateHWND函數獲取的想法)。

另一種解決方案是使用命名管道。

另一種解決方案是通過TCP/IP在本地發送數據。

如果這些字符串只是一個調試字符串,請考慮使用WinAPI中的OutputDebugString函數,並使用像SysInternals'DbgView這樣的程序捕獲它們。

+0

這也是一個好主意。雖然,不,這不是用於調試的目的。 – ahmd0 2013-03-15 09:01:26

1

各種方法,它們中的一些已在上面給出的許多其它方式。哪一個最簡單取決於你的任務。
我也可以建議你filemapping工藝它廣泛用於IPC, DLL是使用文件映射實現的。
它允許mutliply進程共享相同的資源,訪問是隨機的不是必然的。
下面是執行主要步驟:

1.進程A創建一個文件;
2.進程A爲文件創建一個命名系統對象映射文件(映射文件分配內存);
3.進程A創建一個系統對象一個viewOfMapped文件(這可以將進程A的某個區域映射到主存中由mappedFile分配的頁面);
4.進程B創建指定的系統對象mappedfile(名稱應該類似於使用的進程A的名稱),viewOfMapped file;
5.通過viewOfMapped進程返回的指針可以共享相同的內存。 實施例:
方法A:

/* 1. file creation */ 
    hFile = CreateFile(0, GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 
    NULL); 

/* 2. Create file mapping */ 
    wchar_t lpName[] = L"fileMappingObject0"; 
    HANDLE hfileMappingObject; 
    hfileMappingObject = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 1024, lpName); 

/* 3. Create MappedFileViewOfFile */ 
    void* p = (MapViewOfFile(hfileMappingObject, FILE_MAP_ALL_ACCESS, 0, 0, 0)); 

方法B:

/* 2. Create file mapping */ 
     wchar_t lpName[] = L"fileMappingObject0"; 
     HANDLE hfileMappingObject; 
     hfileMappingObject = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 1024, lpName); 

    /* 3. Create MappedFileViewOfFile */ 
     void* p = (MapViewOfFile(hfileMappingObject, FILE_MAP_ALL_ACCESS, 0, 0, 0)); 

這種方法相當簡單,並且也強大。

+0

感謝您的代碼示例。我自己喜歡文件映射技術,除了它有兩個注意事項。首先,映射內存的大小是有限的,並限制爲頁面大小。所以需要編碼某些編組機制來管理傳輸。其次,如果進程在不同高程級別運行,則需要先從高級進程中設置安全描述符,這可能會產生令人討厭的競爭狀態。除此之外,它可能是最快的IPC。 – ahmd0 2013-03-15 17:21:08

相關問題