2016-03-22 124 views
1

我想2個進程之間共享一些數據。第一個將數據寫入映射文件,第二個讀取數據。命名共享內存的Windows API C++

這裏是我到目前爲止的代碼:

第一過程:

#include "stdafx.h" 
    #include <Windows.h> 
    #include <tlhelp32.h> 
    #include <tchar.h> 
    #include<stdio.h> 

    #define BUF_SIZE 256 

    int _tmain(int argc, _TCHAR* argv[]) { 
    TCHAR szName[] = TEXT("Global\\MyFileMappingObject"); 
    LPTSTR szMsg = TEXT("MESS"); 

    HANDLE tokenH; 
    TOKEN_PRIVILEGES tp; 
    LUID luid; 
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &tokenH)) { 
     printf("OpenProcessToken error: %u\n", GetLastError()); 
     return FALSE; 
    } 
    if (!LookupPrivilegeValue(NULL, SE_CREATE_GLOBAL_NAME, &luid)) { 
     printf("LookupPrivilegeValue error: %u\n", GetLastError()); 
     return FALSE; 
    } 
    tp.PrivilegeCount = 1; 
    tp.Privileges[0].Luid = luid; 
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
    if (!AdjustTokenPrivileges(tokenH, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) { 
     printf("AdjustTokenPrivileges error: %u\n", GetLastError()); 
     return FALSE; 
    } 
    if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) 
    { 
     printf("The token does not have the specified privilege. \n"); 
     return FALSE; 
    } 
    CloseHandle(tokenH); 

    HANDLE hMapFile; 
    LPCTSTR pBuf; 
    hMapFile = CreateFileMapping(
     INVALID_HANDLE_VALUE, 
     NULL,      
     PAGE_READWRITE,   
     0,      
     BUF_SIZE,     
     szName); 
    if (hMapFile == NULL) 
    { 
     _tprintf(TEXT("Could not create file mapping object (%d).\n"), 
     GetLastError()); 
     return 1; 
    } 
    pBuf = (LPTSTR)MapViewOfFile(hMapFile, 
     FILE_MAP_ALL_ACCESS, 
     0, 
     0, 
     BUF_SIZE); 

    if (pBuf == NULL) 
    { 
     _tprintf(TEXT("Could not map view of file (%d).\n"), 
     GetLastError()); 

     CloseHandle(hMapFile); 

     return 1; 
    } 
    CopyMemory((PVOID)pBuf, szMsg, (_tcslen(szMsg) * sizeof(TCHAR))); 
    UnmapViewOfFile(pBuf); 
    printf("Done\n"); 
    CloseHandle(hMapFile); 
    return 0; 
} 

第二個過程:

#include "stdafx.h" 
#include <Windows.h> 
#include <tlhelp32.h> 
#include <tchar.h> 
#include <stdio.h> 
#pragma comment(lib, "user32.lib") 

#define BUF_SIZE 256 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    TCHAR szName[] = TEXT("Global\\MyFileMappingObject"); 
    HANDLE tokenH; 
    TOKEN_PRIVILEGES tp; 
    LUID luid; 
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &tokenH); 
    if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) { 
     printf("LookupPrivilegeValue error: %u\n", GetLastError()); 
     return FALSE; 
    } 
    tp.PrivilegeCount = 1; 
    tp.Privileges[0].Luid = luid; 
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
    if (!AdjustTokenPrivileges(tokenH, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) { 
     printf("AdjustTokenPrivileges error: %u\n", GetLastError()); 
     return FALSE; 
    } 
    if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) 
    { 
     printf("The token does not have the specified privilege. \n"); 
     return FALSE; 
    } 
    CloseHandle(tokenH); 

    HANDLE hMapFile; 
    LPCTSTR pBuf; 
    hMapFile = OpenFileMapping(
     FILE_MAP_ALL_ACCESS, // read/write access 
     FALSE,     // do not inherit the name 
     szName);    // name of mapping object 

    if (hMapFile == NULL) 
    { 
     _tprintf(TEXT("Could not open file mapping object (%d).\n"), 
      GetLastError()); 
     return 1; 
    } 
    pBuf = (LPTSTR)MapViewOfFile(hMapFile, // handle to map object 
     FILE_MAP_ALL_ACCESS, // read/write permission 
     0, 
     0, 
     BUF_SIZE); 

    if (pBuf == NULL) 
    { 
     _tprintf(TEXT("Could not map view of file (%d).\n"), 
      GetLastError()); 
     CloseHandle(hMapFile); 
     return 1; 
    } 
    MessageBox(NULL, pBuf, TEXT("Process2"), MB_OK); 
    UnmapViewOfFile(pBuf); 
    CloseHandle(hMapFile); 
    return 0; 
} 

第一個過程設法寫它的數據(我沒有收到任何錯誤消息並獲得「完成」消息),但問題在於第二個過程。 「OpenFileMapping」之後,我從getLastError得到代碼2,它是不存在的文件。我以管理員身份運行兩個進程。

回答

2

錯誤2是ERROR_FILE_NOT_FOUND,這意味着在調用OpenFileMapping()時指定的映射對象不存在。

爲了在進程間共享一個已命名的內核對象,兩個進程都需要在的同一時間運行。與其他命名的內核對象(事件,互斥鎖等)一樣,映射對象也有一個引用計數,每個打開的句柄都增加引用計數。所有手柄關閉後,對象被銷燬。

所以,當第一個應用程序將取消其觀點和關閉其句柄映射對象,該對象將被如果第二個應用程序已經沒有了自己的手柄打開相同的對應對象銷燬。因此,當第二個應用程序嘗試打開它時,該對象將不存在。

+0

現在我想想,這是有道理的。但我有一個新手問題:我如何防止第一個程序停止? –

+0

顯然,你需要編寫一些進入第一個應用程序,它可以等待,不管是一個循環,檢查一個條件要成爲真正的,或者在信號的睡覺等待,或者類似的東西。如果你想第一個應用程序要等到第二應用消費儲值,其中一個方案是通過'CreateEvent創建一個名爲事件對象()'和通過'WaitForSingleObject的上等待()',那麼第二個應用可以打開事件通過'OpenEvent()'並通過'SetEvent()'發送。 –

+0

只是想知道 - 所以在Windows上,您無法真正創建一個「永久」共享內存 - 可以隨時連接到任何進程並與之斷開連接? – SergeyA