Это работает на 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 должен иметь доступ к приложению через файл с отображением памяти. Не нужно менять личность работника. Фактически, я запускаю его в настройках по умолчанию.
какой процесс рабочего процесса учетных данных может быть у него нет разрешения. чтобы проверить попытку установить учетные данные системы и посмотреть, работает ли она –
. В дополнительных настройках ApplicationPool мне нужно изменить Identity на другую учетную запись, такую как пользователь? – chhenning
Да или система, я думаю, это выглядит как проблема. –