如何通过网络在两个 WinForm 应用程序之间调用函数

本文关键字:WinForm 两个 应用程序 之间 函数 调用 网络 何通过 | 更新日期: 2023-09-27 18:35:03

我的大厅里设置了一个视频亭,它让人们签到并打印带有他们的照片、姓名等的徽章。还有一个远程支持工具,不幸的是有时会崩溃。我在信息亭上有一个解决此问题的功能,但您必须立即转到信息亭以触发它。

我还编写了一个管理工具,该工具使用 WMI 来监视和管理展台的其他一些方面。我希望能够通过此应用程序触发此修复功能。我花了无数个小时在谷歌上试图解决这个问题,但没有运气。也许我没有在寻找正确的东西。

我的问题是这个。在 C# 中,如何通过网络从管理应用程序调用展台应用程序中的修复函数?

如何通过网络在两个 WinForm 应用程序之间调用函数

好的,在我的Server窗体上,我有一个运行TcpListener的BackgroundWorker 。您需要将此 TcpListener 放在后台工作线程中,否则您将永远无法阻止它执行,直到它接受 TcpClient。

此外,您需要在执行主线程中处理从此后台线程接收的任何数据,以防止跨线程异常:

private TcpListener _listener;
private const int port = 8000;
private void Worker_TcpListener(object sender, DoWorkEventArgs e) {
  BackgroundWorker worker = sender as BackgroundWorker;
  do {
    try {
      _listener = new TcpListener(IPAddress.Any, port);
      _listener.Start();
      TcpClient client = _listener.AcceptTcpClient(); // waits until data is avaiable
      int MAX = client.ReceiveBufferSize;
      NetworkStream stream = client.GetStream();
      Byte[] buffer = new Byte[MAX];
      int len = stream.Read(buffer, 0, MAX);
      if (0 < len) {
        string data = Encoding.UTF8.GetString(buffer);
        worker.ReportProgress(len, data.Substring(0, len));
      }
      stream.Close();
      client.Close();
    } catch (SocketException) {
      // See MSDN: Windows Sockets V2 API Error Code Doc for details of error code
    } catch (ThreadAbortException) { // If I have to call Abort on this thread
      return;
    } finally {
      _listener.Stop();
    }
  } while (!worker.CancellationPending);
}

这对于大型消息(如 JPEG 文件等(不利,但对于我已编码特殊数据以查找的短字符串非常有用。

此数据被发送回我的主执行线程(使用 ReportProcess 方法(,在那里处理数据:

private void Worker_TcpListener(object sender, ProgressChangedEventArgs e) {
  if (e.UserState != null) {
    int len = e.ProgressPercentage;
    string data = e.UserState.ToString();
    if (!String.IsNullOrEmpty(data) && (3 < len)) {
      string head = data.Substring(0, 3);
      string item = data.Substring(3);
      if (!String.IsNullOrEmpty(item)) {
        if (head == "BP:") {
          string[] split = data.Split(';');
          if (2 < split.Length) {
            string box = split[0].Substring(3); // Box Number
            string qty = split[1].Substring(2); // Quantity
            string customer = split[2].Substring(2); // Customer Name
            MyRoutine(box, qty, customer);
          }
        }
      }
    }
  }
}

上面的代码只是坐着运行一整天。

同时,我工厂里有大约 10 台 Pocket PC 设备,可以随时发送数据。它们的代码是用 VB 编写的,我真的希望我有一天有时间完成我的 C# 版本,但这里是:

Private Sub SendToServer(string serialNum, int qty, string customer)
  Cursor.Current = Cursors.WaitCursor
  Try
    Dim strPacket As String = String.Format("BP:{0};Q:{1};C:{2};", serialNum, qty, customer)
    Dim colon As Integer = p7_txtIPAddress.Text.IndexOf(":")
    Dim host As String = p7_txtIPAddress.Text.Substring(0, colon)
    Dim port As Integer = CInt(p7_txtIPAddress.Text.Substring(colon + 1))
    Dim dataPacket As [Byte]() = Encoding.ASCII.GetBytes(strPacket)
    Using client As New TcpClient(host, port)
      Dim stream As NetworkStream = client.GetStream()
      stream.Write(dataPacket, 0, dataPacket.Length)
    End Using
  Catch err As Exception
    MessageBox.Show(err.Message, "Print To Server TCP Error")
  Finally
    Cursor.Current = Cursors.Default
  End Try
End Function

我不知道这是否是你想做的,但它有效并且可靠。

显然,我在生产中的代码更大,并且包括您不会发现有用的其他内容(即员工验证、错误记录器等(。我已经删掉了很多,我希望我没有删减任何必要的东西。

这至少应该让你知道如何前进。