zoukankan      html  css  js  c++  java
  • WPF下通过附加属性实现单实例启动

    本文没有什么技术含量,单实例启动基本上也是一个做烂了的功能,一搜网上一大把,这里主要是顺便练习一下wpf的附加属性而已。

    代码如下:

    class SingletonWindow
    {
        //注册附加属性
        public static readonly DependencyProperty IsEnabledProperty =
            DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(SingletonWindow), new FrameworkPropertyMetadata(OnIsEnabledChanged));

        public static void SetIsEnabled(DependencyObject element, Boolean value)
        {
            element.SetValue(IsEnabledProperty, value);
        }
        public static Boolean GetIsEnabled(DependencyObject element)
        {
            return (Boolean)element.GetValue(IsEnabledProperty);
        }

        //根据附加属性的返回值使能单实例模式
        public static void OnIsEnabledChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            if ((bool)args.NewValue != true)
            {
                return;
            }

            Process();
            return;
        }

        public static void Process()    //如果不适用附加属性也可以直接使用此函数
        {
            //判断单实例的方式有很多,如mutexprocess,文件锁等,这里用的是process方式

            var process = GetRunningInstance();
            if (process != null)
            {
                HandleRunningInstance(process);
                Environment.Exit(0);
            }
        }

        const int WS_SHOWNORMAL = 1;

        [System.Runtime.InteropServices.DllImport("User32.dll")]
        static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
        [System.Runtime.InteropServices.DllImport("User32.dll")]
        static extern bool SetForegroundWindow(IntPtr hWnd);
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        static extern bool FlashWindow(IntPtr hWnd,bool bInvert);

        static System.Diagnostics.Process GetRunningInstance()
        {
            var current = System.Diagnostics.Process.GetCurrentProcess();
            var processes = System.Diagnostics.Process.GetProcessesByName(current.ProcessName);

            foreach (var process in processes)
            {
                if (process.Id != current.Id)
                    if (System.Reflection.Assembly.GetExecutingAssembly().Location.Replace("/", "\") == current.MainModule.FileName)
                        return process;
            }
            return null;
        }

        static void HandleRunningInstance(System.Diagnostics.Process instance)
        {
            if (instance.MainWindowHandle!=IntPtr.Zero)
            {
                for (int i = 0; i < 2; i++)
                {
                    FlashWindow(instance.MainWindowHandle, 500);
                }

                SetForegroundWindow(instance.MainWindowHandle);
                ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL);
            }
            else
            {
                //else 处理有点麻烦,简化如下
                MessageBox.Show("已经有一个实例在运行,无法启动第二个实例");
            }
        }

        static void FlashWindow(IntPtr hanlde, int interval)
        {
            FlashWindow(hanlde, true);
            System.Threading.Thread.Sleep(interval);
            FlashWindow(hanlde, false);
            System.Threading.Thread.Sleep(interval);
        }
    }

    代码其实很简单,前半部分是注册依赖属性,然后根据依赖属性判断是否启用单实例模式;后半部分就是一个传统的单实例模式的功能了。也就不介绍了。

    使用这段代码也很简单:

      1. Xaml方式:在主窗口的xaml文件中加入附加属性即可
        <Window xmlns:src="clr-namespace:WpfApplication1" src:SingletonWindow.IsEnabled="true">

         

      2. 传统方式:直接使用代码中后半部分,和winform下没什么区别。在主窗口的构造函数里面加入这句话。
        SingletonWindow.Process();
  • 相关阅读:
    Notes about "Exploring Expect"
    Reuse Sonar Checkstyle Violation Report for Custom Data Analysis
    Eclipse带参数调试的方法
    MIT Scheme Development on Ubuntu
    Manage Historical Snapshots in Sonarqube
    U盘自动弹出脚本
    hg的常用配置
    Java程序员的推荐阅读书籍
    使用shared memory 计算矩阵乘法 (其实并没有加速多少)
    CUDA 笔记
  • 原文地址:https://www.cnblogs.com/qizh/p/3843196.html
Copyright © 2011-2022 走看看