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();
  • 相关阅读:
    select、poll和epoll
    Linux 常用命令之文件和目录
    SmartPlant Review 帮助文档机翻做培训手册
    SmartPlant Foundation 基础教程 3.4 菜单栏
    SmartPlant Foundation 基础教程 3.3 标题栏
    SmartPlant Foundation 基础教程 3.2 界面布局
    SmartPlant Foundation 基础教程 3.1 DTC登陆界面
    SmartPlant Foundation 基础教程 1.4 SPF架构
    SmartPlant Foundation 基础教程 1.3 SPF其他功能
    SmartPlant Foundation 基础教程 1.2 SPF集成设计功能
  • 原文地址:https://www.cnblogs.com/qizh/p/3843196.html
Copyright © 2011-2022 走看看