C#WinForm防止窗体多次打开,如果存在,则打开已在运行的程序

例如 我们开发exe程序 当我们双击exe程序 会发现多次重复生成打开新窗体,我们看看微信 确实没有这个问题,始终只会显示一个,如果已登录,在双击直接显示主界面

例如:

如何防止只能打开一次 ,代码如下

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DatabaseTool
{
    internal static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Run();
        }
        /*防止程序被多次运行*/
    
        #region 使用的Win32函数的声明 解决方法3实现方式中存在的问题——只能是最小化的窗体显示出来,如果隐藏到托盘中则不能把运行的程序显示出来

        /// <summary>
        /// 找到某个窗口与给出的类别名和窗口名相同窗口
        /// 非托管定义为:http://msdn.microsoft.com/en-us/library/windows/desktop/ms633499(v=vs.85).aspx
        /// </summary>
        /// <param name="lpClassName">类别名</param>
        /// <param name="lpWindowName">窗口名</param>
        /// <returns>成功找到返回窗口句柄,否则返回null</returns>
        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        /// <summary>
        /// 切换到窗口并把窗口设入前台,类似 SetForegroundWindow方法的功能
        /// </summary>
        /// <param name="hWnd">窗口句柄</param>
        /// <param name="fAltTab">True代表窗口正在通过Alt/Ctrl +Tab被切换</param>
        [DllImport("user32.dll ", SetLastError = true)]
        static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);

        / <summary>
        /  设置窗口的显示状态
        /  Win32 函数定义为:http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx
        / </summary>
        / <param name="hWnd">窗口句柄</param>
        / <param name="cmdShow">指示窗口如何被显示</param>
        / <returns>如果窗体之前是可见,返回值为非零;如果窗体之前被隐藏,返回值为零</returns>
        [DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)]
        public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
        public const int SW_RESTORE = 9;
        public static IntPtr formhwnd;


        #region  可以是托盘中的隐藏程序显示出来
        public static void Run()
        {

            // 只能是最小化的窗体显示出来,如果隐藏到托盘中则不能把运行的程序显示出来
            // 具体问题可以看这个帖子:http://social.msdn.microsoft.com/Forums/zh-CN/6398fb10-ecc2-4c03-ab25-d03544f5fcc9
            Process currentproc = Process.GetCurrentProcess();
            Process[] processcollection = Process.GetProcessesByName(currentproc.ProcessName.Replace(".vshost", string.Empty));
            //  该程序已经运行,
            if (processcollection.Length > 1)
            {
                foreach (Process process in processcollection)
                {
                    if (process.Id != currentproc.Id)
                    {
                        // 如果进程的句柄为0,即代表没有找到该窗体,即该窗体隐藏的情况时
                        if (process.MainWindowHandle.ToInt32() == 0)
                        {
                            // 获得窗体句柄
                            formhwnd = FindWindow(null, "主界面");// 目标窗体的 Text 属性中的字符串
                            // 重新显示该窗体并切换到带入到前台
                            ShowWindow(formhwnd, SW_RESTORE);
                            SwitchToThisWindow(formhwnd, true);
                        }
                        else
                        {
                            // 如果窗体没有隐藏,就直接切换到该窗体并带入到前台
                            // 因为窗体除了隐藏到托盘,还可以最小化
                            SwitchToThisWindow(process.MainWindowHandle, true);
                        }
                    }
                }
            }
            else
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Form1 Login = new Form1();
                Login.ShowDialog();//显示登陆窗体  
                if (Login.DialogResult == DialogResult.OK)
                    Application.Run(new Form2());//判断登陆成功时主进程显示主窗口  
                else return;
            }


        }
        #endregion
        #endregion
    }
}

Form2窗体的代码


        /// <summary>
        ///  双击托盘 显示主界面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            //显示窗体
            this.Show();
            this.ShowInTaskbar = true;//启用任务栏图标                                   
            //notifyIcon1.Visible = false; //将托盘图标设为隐藏           
        }
        /// <summary>
        /// 当关闭窗口时 隐藏当前窗体、隐藏任务栏图标  
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form2_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.Hide(); //隐藏窗体
            this.ShowInTaskbar = false;
            e.Cancel = true;//取消关闭指令
        }

实现效果

参考https://www.cnblogs.com/zhili/p/OnlyInstance.html

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值