在进行WPF开发时,总是在找更加优雅去写单例模式的代码。
很多人都喜欢用Mutex,一个App.cs下很多的Mutex,我也喜欢用。
看完《WPF编程宝典》的第七章Applicaton类后,为了代码的美观和整洁,我就使用了7.2.5章节的《单实例应用程序》的思路来创建项目中的单实例应用。
项目中主要添加Microsoft.VisualBasic引用,写继承自WindowsFormsApplicationBase的Wrapper来控制单例。
public class SingleInstanceAppWrapper : WindowsFormsApplicationBase { private WpfApp app; public SingleInstanceAppWrapper() { this.IsSingleInstance = true; } }
通过在Wrapper的构造函数中设置IsSingleInstance=true来控制单例。
通过重写OnStartupNextInstance来控制单例,这样就多程序就自动通过OnStartupNextInstance来实现了进程间的通信。
protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs) { if (eventArgs.CommandLine.Count > 0) { string arg = eventArgs.CommandLine[0]; //单例中的逻辑 } }
再设计升级程序时因为安全问题,程序提升了权限,还是保持以向单例模式。就在这时候出现问题了!检查升级设置文件权限时发现程序一直再报错。无法继续执行了。
程序启动的时候是计划任务使用管理员权限启动,启动时检查权限,权限正常。
System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent(); System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal(identity); if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator)) { //如果走到这里是管理员。当前程序是管理员 }
而通过启动参数通知程序时OnStartupNextInstance中获取一次权限,竟然不是管理员了。因为当时产品催着上线。所有没有做更多的分析。而是修改了通知方式。不使用启动参数。而更换成了窗体消息。
高权限接收低权限发送的窗体消息时需要在高权限添加消息筛选器。低权限需要发送哪些消息,高权限就需要添加哪些消息到筛选器,不然无法接收。
[DllImport("user32.dll")] public static extern bool ChangeWindowMessageFilterEx(IntPtr HWnd, uint Msg, int WParam, IntPtr LParam);
函数为ChangeWindowMessageFilterEx 具体用法必应一下。