Как остановить / исправить File.Exists от изменения состояния именованного канала? - PullRequest
0 голосов
/ 02 октября 2019

В Windows 10 / Server 2016, если File.Exists () используется для проверки существования именованного канала. Проверка будет успешной, но когда вы попытаетесь открыть именованный канал, она завершится с ошибкой 231 «Все экземпляры канала заняты». Однако в Windows 7 это работает!

Сервер именованных каналов является устаревшимПрограмма Win32 C, которая работает более 18 лет. Эта проблема была обнаружена при попытке использовать программное обеспечение на Sever 2016. Именованные каналы успешно созданы и прекрасно работают с тестовым клиентом, который я написал. Проблема в том, что рабочий клиент был создан в 4GL (Pro-IV), который вызывает File.Exists () перед File.Open (). Который у нас, очевидно, нет исходного кода, чтобы изменить это.

Чтобы упростить расследование проблемы, я создал простой сервер именованных каналов C # для репликации устаревшей программы на C, используя NamedPipeServerStream

Task.Run(async () =>
{
    try
    {
        var outboundStream = new NamedPipeServerStream(
            "outbound", 
            PipeDirection.Out, 
            NamedPipeServerStream.MaxAllowedServerInstances);

        AddStatus("Created Outbound Pipe");
        await outboundStream.WaitForConnectionAsync();

        AddStatus("Have Outbound Connection");
        var writer = new StreamWriter(outboundStream);

        while (outboundStream.IsConnected)
        {
            var line = await blockBuffer.ReceiveAsync();
            writer.WriteLine(line);
            writer.Flush();
        }
    }
    catch(Exception ex)
    {
        AddStatus("Error: " + ex.Message);
    }
    AddStatus("Exit Outbound Task");
});

Код клиента

var outboundPipeName = @"\\.\pipe\outbound";

if (File.Exists(outboundPipeName) == true)
{
    Console.WriteLine("Pipe exits!");
}

IntPtr outboundHandle = CreateFile(outboundPipeName,
                        FileAccess.Read,
                        FileShare.None,
                        IntPtr.Zero,
                        FileMode.Open,
                        FileAttributes.Normal,
                        IntPtr.Zero);

Console.WriteLine(Marshal.GetLastWin32Error());

Console.WriteLine("Hit any key");
Console.ReadKey();

return;

При работе в Windows 10 вывод клиента:

Канал существует!
231
Нажмите любую клавишу

Когда я удаляю File.Exists (), вывод будет выглядеть так:

0
Нажать любую клавишу

На стороне сервераон видит связь и идет в петлю. На клиентской стороне значение дескриптора равно 0xffffffffffffffff, а as show показывает, что GetLastError () равен 231 - «Все экземпляры канала заняты»

Как уже упоминалось, у меня нет доступа к производственному клиентскому коду, который вызывает File.Существует(). И этот код работал в течение многих лет с Server 2003 и Windows 7

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...