2013-06-09 2 views
0

У меня есть следующий фрагмент кода:установить режим сообщения именованный канал

//... 
SafeFileHandle handle = NativeMethods.CreateFile(pipeName, FileAccess.ReadWrite, FileShare.None, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero); 
if (handle.IsInvalid) 
    continue; 
uint mode = (uint)PipeMode.ReadModeMessage; // mode==2 
bool result = NativeMethods.SetNamedPipeHandleState(handle, ref mode, IntPtr.Zero, IntPtr.Zero); 
//... 

Проблема заключается в том, что вызов «SetNamedPipeHandleState» терпит неудачу: результат неверен и GetLastError() возвращает 5 (ERROR_ACCESS_DENIED). Кроме того, труба работает очень хорошо - я могу читать и писать данные. Кроме того, конечно, что он не работает в режиме сообщений - например. содержимое двух вызовов сообщений WriteFile считывается одним вызовом ReadFile. Что я здесь делаю неправильно?

ответ

1

CreateFile открывает клиентский конец именованной трубы, уже созданной чем-то другим, действующим как сервер трубопроводов. Вы не говорите нам в вопросе о том, как создается ваша труба. Труба будет работать только в режиме сообщений, если PipeMode был указан как PIPE_TYPE_MESSAGE, когда труба была создана сервером трубопроводов.

Если труба создана в режиме сообщений, клиент-клиент может выбрать, следует ли читать в режиме сообщения или в режиме байта. Если труба не находится в режиме сообщения, никакая попытка клиентом трубы установить режим чтения сообщения (PIPE_READMODE_MESSAGE) не будет иметь никакого эффекта, так как он не изменит режим трубы.

Вы также не показывают нам, как вы реализовали свой NativeMethods, но если ваши CreateFile параметры отображаются непосредственно к аргументам CreateFile функции Win32, вы только запрашивающий FILE_READ_DATA и FILE_WRITE_DATA права доступа к вашей ручке трубы. Эти права недостаточны, чтобы вы могли позвонить по телефону SetNamedPipeHandleState, что объясняет ошибку отказа в доступе. См the Win32 API documentation:

Ручка должна иметь GENERIC_WRITE доступ к названной трубе для только для записи или чтения трубы/записи, или он должен иметь GENERIC_READ и доступа FILE_WRITE_ATTRIBUTES для трубы только для чтения.

+0

Я уже писал, что труба создается в режиме сообщения в комментарии к ответу Ханса Пассана (который был удален). Я думал, что FileAccess.ReadWrite будет переводить на то же, что и GENERIC_READ | GENERIC_WRITE, но (как вы указали) это не так. –