none
如何限制wpf程序的窗口只能打开一个?防止用户多开窗口。 RRS feed

  • 问题

  • 用户双击wpf的exe程序时或者用户双击文件用wpf的exe打开时,若已经有该程序的窗口打开了,则不再打开另一个,直接把活动窗口指向已经打开的wpf程序。若是双击文件时打开的wpf程序,则把双击文件地址传过去。根据该双击文件的地址做其他处理
    2016年12月8日 5:11

答案


  • Hi 轮回的齿轮,

    请参考下面的实现代码(App.xaml.cs)

     /// <summary>
        /// Interaction logic for App.xaml
        /// </summary>
        public partial class App : Application
        {
    
            /// 该函数设置由不同线程产生的窗口的显示状态
            /// </summary>
            /// <param name="hWnd">窗口句柄</param>
            /// <param name="cmdShow">指定窗口如何显示。查看允许值列表,请查阅ShowWlndow函数的说明部分</param>
            /// <returns>如果函数原来可见,返回值为非零;如果函数原来被隐藏,返回值为零</returns>
            [DllImport("User32.dll")]
            private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
    
            /// <summary>
            ///  该函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号。
            ///  系统给创建前台窗口的线程分配的权限稍高于其他线程。 
            /// </summary>
            /// <param name="hWnd">将被激活并被调入前台的窗口句柄</param>
            /// <returns>如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零</returns>
            [DllImport("User32.dll")]
            private static extern bool SetForegroundWindow(IntPtr hWnd);
    
            private const int SW_SHOWNOMAL = 1;
            private static void HandleRunningInstance(Process instance)
            {
                ShowWindowAsync(instance.MainWindowHandle, SW_SHOWNOMAL);//显示
                SetForegroundWindow(instance.MainWindowHandle);//当到最前端
            }
            private static Process RuningInstance()
            {
                Process currentProcess = Process.GetCurrentProcess();
                Process[] Processes = Process.GetProcessesByName(currentProcess.ProcessName);
                foreach (Process process in Processes)
                {
                    if (process.Id != currentProcess.Id)
                    {
                        if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == currentProcess.MainModule.FileName)
                        {
                            return process;
                        }
                    }
                }
                return null;
            }
    
            private void Application_Startup(object sender, StartupEventArgs e)
            {
                Process process = RuningInstance();
                if (process == null)
                {
                    if (e.Args.Length == 1) //make sure an argument is passed
                    {
                        FileInfo file = new FileInfo(e.Args[0]);
                        if (file.Exists) //make sure it's actually a file
                        {
                            //Do whatever
                            MessageBox.Show(file.FullName);
                        }
                    }
                }
                else
                {
                    MessageBox.Show("应用程序已经在运行中。。。");
                    HandleRunningInstance(process);
                    System.Threading.Thread.Sleep(1000);
                    System.Environment.Exit(1);
                }
            }
    
        }
    

    Best Regards,

    Yohann Lu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2016年12月8日 6:47
    版主

全部回复


  • Hi 轮回的齿轮,

    请参考下面的实现代码(App.xaml.cs)

     /// <summary>
        /// Interaction logic for App.xaml
        /// </summary>
        public partial class App : Application
        {
    
            /// 该函数设置由不同线程产生的窗口的显示状态
            /// </summary>
            /// <param name="hWnd">窗口句柄</param>
            /// <param name="cmdShow">指定窗口如何显示。查看允许值列表,请查阅ShowWlndow函数的说明部分</param>
            /// <returns>如果函数原来可见,返回值为非零;如果函数原来被隐藏,返回值为零</returns>
            [DllImport("User32.dll")]
            private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
    
            /// <summary>
            ///  该函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号。
            ///  系统给创建前台窗口的线程分配的权限稍高于其他线程。 
            /// </summary>
            /// <param name="hWnd">将被激活并被调入前台的窗口句柄</param>
            /// <returns>如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零</returns>
            [DllImport("User32.dll")]
            private static extern bool SetForegroundWindow(IntPtr hWnd);
    
            private const int SW_SHOWNOMAL = 1;
            private static void HandleRunningInstance(Process instance)
            {
                ShowWindowAsync(instance.MainWindowHandle, SW_SHOWNOMAL);//显示
                SetForegroundWindow(instance.MainWindowHandle);//当到最前端
            }
            private static Process RuningInstance()
            {
                Process currentProcess = Process.GetCurrentProcess();
                Process[] Processes = Process.GetProcessesByName(currentProcess.ProcessName);
                foreach (Process process in Processes)
                {
                    if (process.Id != currentProcess.Id)
                    {
                        if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == currentProcess.MainModule.FileName)
                        {
                            return process;
                        }
                    }
                }
                return null;
            }
    
            private void Application_Startup(object sender, StartupEventArgs e)
            {
                Process process = RuningInstance();
                if (process == null)
                {
                    if (e.Args.Length == 1) //make sure an argument is passed
                    {
                        FileInfo file = new FileInfo(e.Args[0]);
                        if (file.Exists) //make sure it's actually a file
                        {
                            //Do whatever
                            MessageBox.Show(file.FullName);
                        }
                    }
                }
                else
                {
                    MessageBox.Show("应用程序已经在运行中。。。");
                    HandleRunningInstance(process);
                    System.Threading.Thread.Sleep(1000);
                    System.Environment.Exit(1);
                }
            }
    
        }
    

    Best Regards,

    Yohann Lu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2016年12月8日 6:47
    版主
  • 参考https://blog.csdn.net/wodeshijianhrf/article/details/78441848

    这是我见过的最优雅的实现单实例的方法,命名管道,充分利用了系统提供的服务,而且还能实现通信

    2021年3月14日 13:45