C# 在程序的另一个实例上显示窗体
我编写了一个程序,它使用ApplicationContext在窗体关闭时继续运行。通过单击托盘图标可以再次显示表单,但我希望它在应用程序再次运行时也显示其表单,而不是运行另一个程序实例 我已经尝试实施问题中建议的解决方案,但我似乎无法让PostMessage发挥作用。我已经成功地实现了命名管道,但是在获取等待消息与ApplicationContext通信的线程时遇到了问题 我知道我见过其他具有此功能的应用程序,所以我的问题是:这通常是如何实现的?我找到的所有解决方案似乎都适用于其他人,所以我肯定错过了一些简单的东西 编辑: 抱歉没有包括一个例子。我解决了这个问题,在设置之前我使用了C# 在程序的另一个实例上显示窗体,c#,multithreading,winforms,C#,Multithreading,Winforms,我编写了一个程序,它使用ApplicationContext在窗体关闭时继续运行。通过单击托盘图标可以再次显示表单,但我希望它在应用程序再次运行时也显示其表单,而不是运行另一个程序实例 我已经尝试实施问题中建议的解决方案,但我似乎无法让PostMessage发挥作用。我已经成功地实现了命名管道,但是在获取等待消息与ApplicationContext通信的线程时遇到了问题 我知道我见过其他具有此功能的应用程序,所以我的问题是:这通常是如何实现的?我找到的所有解决方案似乎都适用于其他人,所以我肯定
SynchronizationContext.Current
。我通过在构建表单之后而不是之前构建MessageReceiver类来修复它。这是我的代码,以防有人发现它有用
在程序
类中:
private const byte Activate = 3 << 3;
[STAThread]
private static void Main()
{
using (var mtx =
new Mutex(true, "{F6878DF0-C021-4B4F-934A-7FB03957E09F}",
out var createdNew))
{
if (createdNew)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new AppContext(Activate));
}
else
{
//if the program is already running, make a NamedPipeServer
//and wait for it to connect, then write the Activate message
using (var pipeServer =
new NamedPipeServerStream("testpipe",
PipeDirection.Out))
{
pipeServer.WaitForConnection();
pipeServer.WriteByte(Activate);
}
}
}
}
private class MessageReceiver
{
public event EventHandler MessageReceived;
private readonly SynchronizationContext _sync;
private Thread _waitThread;
private readonly byte _activate;
public MessageReceiver(byte activateMessage)
{
_sync = SynchronizationContext.Current;
_activate = activateMessage;
}
public void StopWait()
{
_waitThread.Abort();
}
private void WaitInternal()
{
while (true)
{
using (var client = new NamedPipeClientStream(
".", "testpipe", PipeDirection.In))
{
//block until we can connect to the pipe server
client.Connect();
//read a byte from the stream and check if it's
//the activate signal
if (client.ReadByte() != _activate) continue;
//if so, invoke the MessageRecieved event on the
//thread that created the MessageReceiver
_sync.Send(
state =>
MessageReceived?.Invoke(
this, EventArgs.Empty), null);
}
}
}
public void BeginWait()
{
if (_waitThread.ThreadState == ThreadState.Running
|| _waitThread.ThreadState == ThreadState.AbortRequested)
return;
_waitThread = new Thread(WaitInternal);
_waitThread.Start();
}
}
MessageReceiver
类:
private const byte Activate = 3 << 3;
[STAThread]
private static void Main()
{
using (var mtx =
new Mutex(true, "{F6878DF0-C021-4B4F-934A-7FB03957E09F}",
out var createdNew))
{
if (createdNew)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new AppContext(Activate));
}
else
{
//if the program is already running, make a NamedPipeServer
//and wait for it to connect, then write the Activate message
using (var pipeServer =
new NamedPipeServerStream("testpipe",
PipeDirection.Out))
{
pipeServer.WaitForConnection();
pipeServer.WriteByte(Activate);
}
}
}
}
private class MessageReceiver
{
public event EventHandler MessageReceived;
private readonly SynchronizationContext _sync;
private Thread _waitThread;
private readonly byte _activate;
public MessageReceiver(byte activateMessage)
{
_sync = SynchronizationContext.Current;
_activate = activateMessage;
}
public void StopWait()
{
_waitThread.Abort();
}
private void WaitInternal()
{
while (true)
{
using (var client = new NamedPipeClientStream(
".", "testpipe", PipeDirection.In))
{
//block until we can connect to the pipe server
client.Connect();
//read a byte from the stream and check if it's
//the activate signal
if (client.ReadByte() != _activate) continue;
//if so, invoke the MessageRecieved event on the
//thread that created the MessageReceiver
_sync.Send(
state =>
MessageReceived?.Invoke(
this, EventArgs.Empty), null);
}
}
}
public void BeginWait()
{
if (_waitThread.ThreadState == ThreadState.Running
|| _waitThread.ThreadState == ThreadState.AbortRequested)
return;
_waitThread = new Thread(WaitInternal);
_waitThread.Start();
}
}
请出示你的密码。我们需要一个命名管道,这是一个很好的方向。分享与该部分相关的代码以及您遇到问题的地方。有不同的可能性。使用互斥体、消息、命名管道、UI自动化或上述部分/全部的组合(也是互斥体+注册表项或RegisterWindowMessage+PostThreadMessage/PostMessage…)。您需要展示您正在做的事情,并解释在定义的情况下它在哪里失败或不能按预期工作。此代码重新发明了一个已经在.NET Framework中实现的功能。