Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当启动此可执行程序的另一个实例时,如何更新正在运行的应用程序的WinForms控件?_C#_Winforms_Process_Multiple Instances_Single Instance - Fatal编程技术网

C# 当启动此可执行程序的另一个实例时,如何更新正在运行的应用程序的WinForms控件?

C# 当启动此可执行程序的另一个实例时,如何更新正在运行的应用程序的WinForms控件?,c#,winforms,process,multiple-instances,single-instance,C#,Winforms,Process,Multiple Instances,Single Instance,我制作了单实例应用程序,但我的问题是,我不知道如何获取第一个打开的FormMain实例并更新表单文本框! 你能帮我吗 static void Main(string[] args) { bool result; Mutex mutex = new System.Threading.Mutex(true, "unique_name", out result); if (!result) { **/* CAL

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

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);
}

您可以使用命名管道进程间通信,如下所示:

使用

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;
静态变量

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 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 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();
}
测试

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();
}
用法

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

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

此外,您还可以改进这种简单的行为,使其具有更复杂的系统,使用类框架而不是字符串命令

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

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线程同步:

一些链接

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;


您可以向另一进程的主窗口发送标准Windows消息,并使原始进程更新其自己的控件。无法从另一个进程执行此操作。请使用事件,如中所示。@Alejandro我怀疑可能需要WM_uuuCopyData消息。@MartinJames如果需要传递大量数据,这可能是一个很好的候选消息;如果只需要一个通知,则可以使用自定义消息。