如何在启动此可执行程序的另一个实例时更新 运行 应用程序的 WinForms 控件?
How to update a WinForms control of a running application when another instance of this executable program is launched?
我制作了单实例应用程序,但我的问题是,我不知道如何获取第一个打开的 FormMain 实例并更新表单 TextBox!
你能帮帮我吗?
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;
应用程序唯一标识符
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 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 线程同步:
How do I update the GUI from another thread?
部分链接
Full Duplex Asynchronous Read/Write with Named Pipes (CodeProject)
Inter Process Communication (C# Vault)
WCF Comparison with Web Services and .NET Remoting (CodeProject)
Socket Programming In C# (C-SharpCorner)
我制作了单实例应用程序,但我的问题是,我不知道如何获取第一个打开的 FormMain 实例并更新表单 TextBox! 你能帮帮我吗?
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;
应用程序唯一标识符
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 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 线程同步:
How do I update the GUI from another thread?
部分链接
Full Duplex Asynchronous Read/Write with Named Pipes (CodeProject)
Inter Process Communication (C# Vault)
WCF Comparison with Web Services and .NET Remoting (CodeProject)
Socket Programming In C# (C-SharpCorner)