2015-08-25 10 views
0

У меня есть веб-интерфейс API с контроллером, который должен связываться с локальным инструментом через файл с отображением памяти. Когда я пытаюсь открыть такой файл с помощью OpenExisting, я получаю ошибку «файл не найден».Как скомпилировать файл с памятью из веб-API?

string MMF_In_Name = "MemoryMappedFilename"; 
MemoryMappedFile MMF_In = MemoryMappedFile.OpenExisting(MMF_In_Name); 

Я попытался добавить префикс «Global /» на имя, но безуспешно.

Далее я попытался запустить инструмент командной строки с моего контроллера. Инструмент запускается, но он получает тот же «файл, который не найден». Когда я запускаю инструмент, все работает отлично. Это означает, что имя файла верное.

Как я могу убедить рабочего IIS позволить мне открывать и использовать файл с отображением памяти?

Я использую Windows Server 2012 и ISS 8.5.

+0

какой процесс рабочего процесса учетных данных может быть у него нет разрешения. чтобы проверить попытку установить учетные данные системы и посмотреть, работает ли она –

+0

. В дополнительных настройках ApplicationPool мне нужно изменить Identity на другую учетную запись, такую ​​как пользователь? – chhenning

+0

Да или система, я думаю, это выглядит как проблема. –

ответ

2

Это работает на Windows Server 2012 и IIS 8.5.

Важно понимать, что рабочий IIS работает на другом сеансе сервера терминалов, чем обычные приложения. Очень похоже на службу Windows.

Поэтому, когда приложение, открывающее файл с памятью, ему нужно создать его с помощью префикса «Глобальный», добавленного к имени. Но также необходимо добавить дескриптор безопасности или идентификатор. В C# это будет выглядеть следующим образом:

string MMF_Name = @"Global\MyMemoryMappedFileName"; 

var security = new MemoryMappedFileSecurity(); 
security.AddAccessRule(new System.Security.AccessControl.AccessRule<MemoryMappedFileRights>(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MemoryMappedFileRights.FullControl, AccessControlType.Allow)); 


var mmf = MemoryMappedFile.CreateOrOpen(MMF_Name 
    , 1024 * 1024 
    , MemoryMappedFileAccess.ReadWrite 
    , MemoryMappedFileOptions.None 
    , security 
    , System.IO.HandleInheritability.Inheritable); 

В C++ это будет выглядеть следующим образом:

TCHAR szName[] = TEXT("Global\MyMemoryMappedFileName"); 

HANDLE hMapFile; 
LPCTSTR pBuf; 

SECURITY_DESCRIPTOR sd; 

if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) 
    printf("InitializeSecurityDescriptor failed %d\n", GetLastError()); 

if (!SetSecurityDescriptorDacl(&sd, true, 0, false)) 
    printf("SetSecurityDescriptorDacl failed %d\n", GetLastError()); 

SECURITY_ATTRIBUTES sa; 
sa.nLength = sizeof(sa); 
sa.lpSecurityDescriptor = &sd; 
sa.bInheritHandle = false; 



hMapFile = CreateFileMapping(
    INVALID_HANDLE_VALUE, // use paging file 
    &sa,     // default security 
    PAGE_READWRITE,   // read/write access 
    0,      // maximum object size (high-order DWORD) 
    BUF_SIZE,    // maximum object size (low-order DWORD) 
    szName);     // name of mapping object 

if (hMapFile == NULL) 
{ 
    _tprintf(TEXT("Could not create file mapping object (%d).\n"), 
     GetLastError()); 
    return 1; 
} 

Приложение создания таких объектов необходимо начать с правами администратора.

Теперь, когда клиент, как и работник IIS, пытается получить доступ к файлу, ему необходимо использовать правильное имя, а также использовать префикс «Глобальный». В C# это будет выглядеть так:

string MMF_Name = @"Global\MyMemoryMappedFileName"; 

var MMF = MemoryMappedFile.OpenExisting(MMF_Name 
    , MemoryMappedFileRights.ReadWrite 
    , HandleInheritability.Inheritable); 

В C++:

TCHAR szName[] = TEXT("Global\\MyMemoryMappedFileName"); 

HANDLE hMapFile; 
LPCTSTR pBuf; 

hMapFile = OpenFileMapping(
    FILE_MAP_ALL_ACCESS, // read/write access 
    TRUE,     // !!!!! do inherit the name 
    szName);    // name of mapping object 

if (hMapFile == NULL) 
{ 
    _tprintf(TEXT("Could not open file mapping object (%d).\n"), 
     GetLastError()); 
    return 1; 
} 

Когда все это сделано. Работник IIS должен иметь доступ к приложению через файл с отображением памяти. Не нужно менять личность работника. Фактически, я запускаю его в настройках по умолчанию.