Возникли проблемы при подключении к именованному каналу из программы Win32 на C++

У меня есть две программы, которые работают на одном компьютере, и мне нужно, чтобы они разговаривали. Одним из них является существующая программа, написанная на C++ с использованием более старой платформы Windows32. Другой - недавно написанное приложение C#, использующее.NET Framework. Мое новое.NET-приложение будет действовать как сервер, а старое существующее приложение - как клиент.

У меня есть именованный канал, созданный как на клиенте, так и на сервере. Я просто не могу заставить их подключиться. Я подозреваю, что проблема просто в том, что я не сопоставляю имя файла правильно (именованные каналы используют файлы в фоновом режиме).

Вот код сервера.NET:

    private volatile NamedPipeServerStream pipeServer;
    pipeServer = new NamedPipeServerStream("MyPipe", PipeDirection.InOut);
    pipeServer.WaitForConnection();

Вот старый существующий код клиента win32:

HANDLE pipe = CreateFile(
    "\\Device\\NamedPipe\\MyPipe",
    GENERIC_READ | GENERIC_WRITE, // only need read access
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL
);

Сначала я запускаю код сервера, и он сидит в ожидании соединения. Каждый раз, когда моя ручка равна INVALID_HANDLE_VALUE,

Я использовал ProcessExplorer, чтобы посмотреть, смогу ли я найти истинное имя канала. В соответствии с ProcessExplorer это имя \ Device \ NamedPipe \ MyPipe.

Я думаю, что я соответствую этому на моей стороне клиента. Если кто-то может дать предложение, я благодарен. Благодарю.

2 ответа

Решение

Чтобы открыть именованную трубу с CreateFileнеобходимо указать имя файла как \\.\pipe\nameтак что в вашем случае это будет выглядеть так:

HANDLE pipe = CreateFile(
    "\\\\.\\Pipe\\MyPipe",
    GENERIC_READ | GENERIC_WRITE, // only need read access
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL
);

Настройка PipeSecurity решил эту проблему для меня. Сделать его доступным для Everyone выглядит менее безопасно, но это сработало.

PipeSecurity ps = new PipeSecurity();
PipeAccessRule psRule = new PipeAccessRule(@"Everyone", PipeAccessRights.ReadWrite, System.Security.AccessControl.AccessControlType.Allow);
ps.AddAccessRule(psRule);
 NamedPipeServerStream pipeServer = new NamedPipeServerStream("datapipe", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous, 1, 1, ps);

Источник: Ошибка именованного канала - System.UnauthorizedAccessException: Доступ к пути запрещен.

Другие вопросы по тегам