Myrkjartan Hrolfr Ответов: 1

Запись из namedpipeclientstream в namedpipeserverstream через приложения WPF


У меня есть программа, которая должна взаимодействовать с другой программой, которая вызывается с самого начала.
Мне удалось отправить необходимые данные из первой программы во вторую с помощью NamedPipes.
Когда вторая программа закроется, мне нужно будет отправить некоторые данные обратно в первую программу. Я настроил NamedPipeServerStream в первой программе, а из события закрытия второй программы-NamedPipeClientStream. Насколько я могу судить, синхронизация труб не работает должным образом, но я не знаю почему.

Это код из первой программы:
private const string CLIENTPROC = "C:\\Users\\Maik\\Source\\Repos\\PipeTest\\PipeClient\\obj\\x86\\Release\\PipeClient.exe";
private ManualResetEvent threadResetEvent;
private Thread threadHandlePipeSendLast;
private Process procClient;
private string msgPipeSend;
private volatile bool bMsgPipeSend;
public MainWindow()
{
    InitializeComponent();
    this.threadResetEvent = new ManualResetEvent(false);
    System.Diagnostics.Debug.WriteLine("### starting thread");
    this.threadHandlePipeSendLast = new Thread(new ThreadStart(this.ExchangeMapOverlayFileServer));
    this.threadHandlePipeSendLast.Start();
}

private void ExchangeMapOverlayFileServer()
{
    System.Diagnostics.Debug.WriteLine("server thread started");
    Thread.CurrentThread.Name = "apocalypse";
    try
    {
        using (NamedPipeServerStream namedPipeServer = new NamedPipeServerStream("ClosingPipe", PipeDirection.In, 1, PipeTransmissionMode.Byte))
        {
            string line;

            namedPipeServer.WaitForConnection();
            StreamReader sr = new StreamReader(namedPipeServer);
            Thread.Sleep(100);
            line = sr.ReadLine();
            handleRecvMsgFromPipe(line);
            namedPipeServer.Disconnect();
            namedPipeServer.Close();
        }
    }
    catch (Exception e)
    {
        System.Diagnostics.Debug.WriteLine("### " + e.Message + "\n" + e.StackTrace);
    }
}

private void handleRecvMsgFromPipe(string line)
{
    this.outbox.Text = line;
}

private void buttonOpenFormClient_Click(object sender, EventArgs e)
{
G


    if (this.procClient == null)
    {
        try
        {
            this.procClient = Process.Start(new ProcessStartInfo(CLIENTPROC));
        }
        catch (Exception exc)
        {
            MessageBox.Show(exc.Message, "Error");
        }
    }

}


это код из второй программы

private ManualResetEvent threadResetEvent;
private Thread threadHandlePipeSendLast;

private string msgPipeSend;
private volatile bool bMsgPipeSend;
private bool done;

public MainWindow()
{
    InitializeComponent();
    this.threadResetEvent = new ManualResetEvent(false);
    this.Closing += (s, a) =>
    {
        System.Diagnostics.Debug.WriteLine("+++ FormClosing started.");
        this.threadHandlePipeSendLast = new Thread(new ThreadStart(this.HandleWindowClosing));
        this.threadHandlePipeSendLast.Start();
        while (!done)
        {
            Thread.Sleep(1000);
        }
    };
}

private void HandleWindowClosing()
{
    try
    {
        using (NamedPipeClientStream namedPipeClient = new NamedPipeClientStream(".", "ClosingPipe", PipeDirection.Out))
        {
            namedPipeClient.Connect();
            StreamWriter sw = new StreamWriter(namedPipeClient);
            //sw.AutoFlush = true;
            sw.WriteLine("last message");
            namedPipeClient.WaitForPipeDrain();
            namedPipeClient.Close();
            this.done = true;
        }

    }
    catch (Exception e) { System.Diagnostics.Debug.WriteLine(e.Message + "\n" + e.StackTrace); }
}



Где же моя ошибка?
Спасибо.

Что я уже пробовал:

Я пытался:
- использование WaitForPipeDrain (), который просто игнорируется/ ничего не делает
- для управления потоками с помощью Sleep() в различных точках кода
- для переключения сервера и клиента
- Pipedirection.InOut на обоих концах
- Клиент с PipeDirection.Выход, сервер с PipeDirection.В (что мне действительно нужно)

1 Ответов

Рейтинг:
2

RickZeeland

Может ты попробуешь ФОС, Я когда-то использовал его для двусторонней связи между Трей-приложением и службой Windows, и это работало без каких-либо проблем: NetNamedPipeBinding | Microsoft Docs[^]


Myrkjartan Hrolfr

Спасибо за ваш ответ. Тем временем я решил эту проблему, проведя заключительное мероприятие cirumventing.