启动此可执行程序的另一个实例时,如何更新正在运行的应用程序的 WinForms 控件? [英] How to update a WinForms control of a running application when another instance of this executable program is launched?

查看:64
本文介绍了启动此可执行程序的另一个实例时,如何更新正在运行的应用程序的 WinForms 控件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我制作了单实例应用程序,但我的问题是,我不知道如何获取第一个打开的 FormMain 实例并更新表单 TextBox!你能帮我吗?

I made single instance app, but my problem is, I don't know how to get the first opened FormMain instance and update the form TextBox! Could you help me?

static void Main(string[] args)
{
    bool result;
    Mutex mutex = new System.Threading.Mutex(true, "unique_name", out result);

    if (!result)
    {
        **/* 
          CALL OPENED FORM INSTANCE AND UPDATE TEXTBOX
         */**

        return;
    }

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(true);
    Application.Run(new FormMain(args));

    GC.KeepAlive(mutex);
}

推荐答案

你可以像这样使用命名管道进程间通信:

You can use named pipeline interprocess communication like that:

使用

using System;
using System.IO.Pipes;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;

静态变量

static public bool AllowApplicationMultipleInstances { get; private set; } = true;

static private Mutex ApplicationMutex;

static private NamedPipeServerStream IPCServer;

应用唯一标识符

static public string GetGUID()
{
  object[] attributes = Assembly.GetExecutingAssembly()
                                .GetCustomAttributes(typeof(GuidAttribute), false);
  return ( (GuidAttribute)attributes[0] ).ToString();
}

只检查一个实例并初始化服务器

static private bool CheckApplicationOnlyOneInstance(AsyncCallback duplicated)
{
  AllowApplicationMultipleInstances = false;
  string guid = GetGUID();
  ApplicationMutex = new Mutex(true, guid, out bool created);
  if ( created )
    CreateIPCServer(duplicated);
  else
  {
    var client = new NamedPipeClientStream(".", guid, PipeDirection.InOut);
    client.Connect();
    new BinaryFormatter().Serialize(client, "BringToFront");
    client.Close();
  }
  return created;
}

创建服务器

static private void CreateIPCServer(AsyncCallback duplicated)
{
  IPCServer = new NamedPipeServerStream(GetGUID(),
                                        PipeDirection.InOut,
                                        1,
                                        PipeTransmissionMode.Message,
                                        PipeOptions.Asynchronous);
  IPCServer.BeginWaitForConnection(duplicated, IPCServer);
}

请求响应

static private void IPCRequest(IAsyncResult ar)
{
  var server = ar.AsyncState as NamedPipeServerStream;
  server.EndWaitForConnection(ar);
  var command = new BinaryFormatter().Deserialize(server) as string;
  if ( command == "BringToFront" )
  {
    Console.WriteLine(command);
    //MainForm.Instance.SyncUI(() => MainForm.Instance.MenuShowHide_Click(null, null));
  }
  server.Close();
  CreateIPCServer(IPCRequest);
}

测试

static private void Test()
{
  if ( !SystemManager.CheckApplicationOnlyOneInstance(IPCRequest) )
    return;
  Console.ReadKey();
}

使用

您可以根据需要创建字符串命令.

You can create as string commands as needed.

例如,它允许将命令行参数从刚启动的进程传递到实际运行的进程.

For example it allows to pass command line arguments from a process just started to the actual running process.

你也可以改进这个简单的行为来拥有一个更复杂的系统,使用类框架而不是字符串命令.

Also you can improve this simple behavior to have a more complex system, to use a classes framework instead of string commands.

对于您的应用程序,您应该能够使用:

For your application you should be able to use:

static public FormMain MainForm;

static void Main(string[] args)
{
  if ( !SystemManager.CheckApplicationOnlyOneInstance(IPCRequest) )
    return;
  Application.EnableVisualStyles();
  Application.SetCompatibleTextRenderingDefault(true);
  MainForm = new FormMain(args);
  Application.Run(MainForm);
}

如果修改 WinForm 控件,则必须与主 UI 线程同步:

If you modify a WinForm control you must to synchronize with the main UI thread:

如何从另一个线程更新 GUI?

如何从另一个线程访问 WinForms 控件,即与 GUI 线程同步?

一些链接

PipeStream

全双工异步读取/使用命名管道写入 (CodeProject)

进程间通信(C# Vault)

这篇关于启动此可执行程序的另一个实例时,如何更新正在运行的应用程序的 WinForms 控件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆