C# 当启动此可执行程序的另一个实例时,如何更新正在运行的应用程序的WinForms控件?
我制作了单实例应用程序,但我的问题是,我不知道如何获取第一个打开的FormMain实例并更新表单文本框! 你能帮我吗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
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如果需要传递大量数据,这可能是一个很好的候选消息;如果只需要一个通知,则可以使用自定义消息。