wpf 单例

本文告诉大家如何做一个 wpf 单例程序。单例就是用户只能运行这个程序一次,也就是内存只有存在这个程序一个。

首先创建项目,右击 App.xaml.cs 选择编译为 Page ,原来是 ApplicationDefinition

打开 App.xaml 删除StartupUri="MainWindow.xaml",不然下面的代码会启动两个窗口

然后创建 Main ,请添加下面代码

    public partial class App : Application
    {
        App()
        {
            InitializeComponent();
        }

        [STAThread]
        static void Main()
        {
            App app = new App();
            MainWindow window = new MainWindow();
            app.Run(window);
        }
    }

然后就在 Main 写逻辑,这里判断是否有全局锁,如果有就不启动。添加锁的代码很简单。

static Mutex mutex = new Mutex(true, "lindexi");

如果程序没有启动,那么通过下面的代码判断现在只有他一个软件

if (_mutex.WaitOne(TimeSpan.Zero, true))

现在的主函数就是判断可以启动就创建窗口

        static void Main()
        {
            App app = new App();
            if (_mutex.WaitOne(TimeSpan.Zero, true))
            {
                //如果申请成功
                MainWindow window = new MainWindow();
                app.Run(window);
            }
        }

但是如果不能启动,就需要启动原来启动的程序。这里使用一个特殊方法,先创建一个类,可以发送消息给原先的程序。需要知道,在windows上,程序和系统通信都是使用消息,通过模拟消息就可以让其他程序做出特殊的效果,如让他放在窗口最前。

如果需要发送消息,那么需要使用下面的方法。下面代码注册了一个自己的消息,这样在自己的程序可以判断WM_SHOWME来把自己给用户。

    internal class NativeMethods
    {
        public const int HWND_BROADCAST = 0xffff;
        public static readonly int WM_SHOWME = RegisterWindowMessage("WM_SHOWME");
        [DllImport("user32")]
        public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);
        [DllImport("user32")]
        public static extern int RegisterWindowMessage(string message);
    }

接着修改主函数,在已经启动一个程序,就让他打开。这个方法就是发送一个特殊的消息,只有自己的程序知道这个消息是显示。

        static void Main()
        {
            App app = new App();
            if (_mutex.WaitOne(TimeSpan.Zero, true))
            {
                //如果申请成功
                MainWindow window = new MainWindow();
                app.Run(window);
                _mutex.ReleaseMutex();
            }
            else
            {
                NativeMethods.PostMessage(
                    (IntPtr) NativeMethods.HWND_BROADCAST,
                    NativeMethods.WM_SHOWME,
                    IntPtr.Zero,
                    IntPtr.Zero);
            }
        }

然后发送消息需要让程序自己监听,于是打开 MainWindow.xaml.cs 添加下面的代码,如果监听消息是让自己显示,那么就打开自己。

        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
            source.AddHook(WndProc);
        }

        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
        {
            if (msg == NativeMethods.WM_SHOWME)
            {
                Activate();
            }
            return IntPtr.Zero;
        }

这样就可以运行一个程序,再次打开也会打开原来的程序。

但是程序有一个坑,如果是多用户,那么打开只能是一个程序,请看下面的代码。

        private static Mutex _mutex = new Mutex(true, "lindexi" + Environment.UserName);

实际文章就想说如何在多用户系统使用单例。

参见:Writing a custom Main() method for WPF applications — The Stochastic Game

C# .NET Single Instance Application - Sanity Free Coding - C#, .NET, PHP

代码:wpf 单例 PfalmcYmgtx-CSDN下载


本文会经常更新,请阅读原文: https://lindexi.gitee.io/lindexi/post/wpf-%E5%8D%95%E4%BE%8B.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接: https://lindexi.gitee.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

性能优化工具 MVC Mini Profiler

MVC MiniProfiler是Stack Overflow团队设计的一款对ASP.NET MVC、WebForm 以及WCF 的性能分析的小程序。可以对一个...

23280
来自专栏逍遥剑客的游戏开发

.Net用的SQLite

15930
来自专栏程序员与猫

ASP.NET Core 介绍和项目解读

标签: ASP.NETCore 1. 前言 作为一个.NET Web开发者,我最伤心的时候就是项目开发部署时面对Windows Server上贫瘠的解决方案...

28260
来自专栏.NET技术

Visual Studio Package 插件开发

  这段时间公司新做了一个支付系统,里面有N个后台服务,每次有更新修改,拷贝打包发布包“不亦乐乎”。。。于是我想要不要自己定制个打包插件。

17630
来自专栏Windows Community

Windows 商店应用中使用 Office 365 API Tools

本篇我们介绍一个API 工具,用于在 Windows Store App 中使用 Office 365 API。 首先来说一下本文的背景: 使用 SharePo...

391100
来自专栏张善友的专栏

Lightweight Test Automation Framework之旅

Lightweight Test Automation Framework是ASP.NET QA团队开发的自动化集成测试框架,并且应用在ASP.NET QA团队...

23690
来自专栏张善友的专栏

开发人员应该知道Windows 7的十大技巧

最近我在笔记本上安装了64位的Windows 7,今天逛的时候看到Scott Hanselman’s 写的一篇文章Top 10 Tips Working Dev...

19250
来自专栏张善友的专栏

ASP.NET SignalR 高可用设计

在 One ASP.NET 的架构图中,微软将 WebAPI 和 SignalR 归类到 Services 类型与 MVC、Web Forms 同列为一等公民,...

28170
来自专栏Golang语言社区

IntelliJ idea配置Go开发环境

IntelliJ idea一个月,甚得我心,终弃Sublime、liteIDE。 IntelliJ idea是非常强大的一款IDE,支持丰富的插件。安装配置都是...

89560
来自专栏张善友的专栏

ASP.NET Identity 2新增双重认证、帐号锁定、防伪印章功能并修复了一些bug

Microsoft最近发布了ASP.NET Identity 2,该版本支持双重认证、帐号锁定以及防伪印章功能,还增强了用户帐号和索引。此外新版本还包含一个改进...

21080

扫码关注云+社区

领取腾讯云代金券