WPF实现软件只能打开一次,重复点击图标时将上一次打开的软件前置(进程间通信)
重写app.xaml
protected override void OnStartup(StartupEventArgs e)
{
Config.mutex = new System.Threading.Mutex(true, "OnlyRun_mySW");
if (Config.mutex.WaitOne(0, false))//判断软件是否已经开启
{
base.OnStartup(e);
}
else
{
int hWnd = (int)FindWindow(null, "MessageWindow");
SendMessage(hWnd, Message.WM_TEST, 888, 888);//向上次已经打开的软件发送消息
Process.GetCurrentProcess().Kill();
}
}
[DllImport("User32.dll", EntryPoint = "SendMessage")]
public static extern int SendMessage(int hWnd, int msg, int wParam, int lParam); //发送消息
[DllImport("User32.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
创建一个消息窗体用于接收消息,我创建了一个高度为0宽度为0的winform窗体,起名为MessageWindow,设置ShowInTaskbar为false
这么创建的原因是无论主窗体被隐藏,最小化,或者放入托盘栏都能接受到消息
消息窗体代码
public partial class MessageWindow : Form
{
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
public MessageWindow()
{
InitializeComponent();
}
protected override void WndProc(ref System.Windows.Forms.Message m)
{
if(m.Msg== Message.WM_TEST)
{
if(m.WParam.ToString()=="888"&& m.LParam.ToString()=="888")
{
var window = System.Windows.Application.Current.MainWindow as MainWindow;
window.ShowMainWindow();//这个方法是主窗体中我自己写的方法
return;
}
}
base.WndProc(ref m);
}
private void MessageWindow_Load(object sender, EventArgs e)
{
IntPtr HWND_MESSAGE = new IntPtr(-3);
SetParent(this.Handle, HWND_MESSAGE);
}
}
class Message
{
public const int USER = 0X0400;
public const int WM_TEST = USER + 101;
public const int WM_MSG = USER + 102;
}
主窗体代码
public MainWindow()
{
MessageWindow messageWindow = new MessageWindow();
messageWindow.Show();//软件启动时创建消息窗体
InitializeComponent();
}
public void ShowMainWindow()
{
//打开主界面
if (WindowState == WindowState.Minimized)
{
WindowState = WindowState.Normal;
}
Show();
Activate();
}
ps:由于代码是从项目中拷出来的,或许会有点不完整?不过应该没问题