В 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