需求:
1、仅允许打开一个实例;
2、当用户尝试打开第二个时,将已运行的程序从任意状态下激活;
3、当前程序有以下几种状态:a.正常窗口显示;b.最大化显示;c.最小化显示;d.隐藏到托盘;
解决方案:
1、调用VB单实例;
2、处理窗体恢复;
步骤:
1、引用Microsoft.VisualBasic.dll
2、打开Program.cs修改如下:
using System;
using System.Windows.Forms;
using Microsoft.VisualBasic.ApplicationServices;//注意添加这个引用
namespace Test
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(new FormMain());
string[] args = Environment.GetCommandLineArgs();
SingleInstanceController controller = new SingleInstanceController();
controller.Run(args);
}
public class SingleInstanceController : WindowsFormsApplicationBase
{
public SingleInstanceController()
{
IsSingleInstance = true;
StartupNextInstance += this_StartupNextInstance;
}
void this_StartupNextInstance(object sender, StartupNextInstanceEventArgs e)
{
FormMain form = MainForm as FormMain; //My derived form type
form.ReDisplay();//这个方法是处理窗体状态的,自己想要最大化还是正常显示都可以
}
protected override void OnCreateMainForm()
{
MainForm = new FormMain();//注意改成自己的窗体
}
}
}
}
3、在自己的主窗体中实现处理的方法,下面的方法是我自己用的做为示例,可以改成你需要的
/// <summary>
/// 恢复窗体显示,当启动另外一个实例时,当前实例自动恢复窗体显示
/// </summary>
public void ReDisplay()
{
if (WindowState == FormWindowState.Minimized)
{
WindowState = FormWindowState.Normal;//还原窗体显示
this.Activate();//激活窗体并给予焦点
this.ShowInTaskbar = true;//显示任务栏图标
notifyIcon1.Visible = false;//托盘图标隐藏
}
}
注:
1、这个方法是自己实现窗体显示的方法,所以不会像网上其它解决方案一样只能从最小化状态下恢复;
2、调用了VB的DLL在安全模式下运行会出问题,其它方面也有可能出现问题,建议使用前先自行了解一下;
3、这个方法已运行的窗体并不会在桌面最前端显示,但会在任务栏上闪烁,当然这个也好解决,获取句柄前端显示就可以了,我这个程序没这个需求,所以没有加。