App.xaml.cs

         protected override void OnStartup(StartupEventArgs e)
{
//禁止二次启动
this.Startup += new StartupEventHandler(App_Startup);
base.OnStartup(e);
}
#region 禁止二次启动
// 用于激活已打开的窗体
[DllImport("user32.dll")]
public static extern void SetForegroundWindow(IntPtr hwnd);
//操作当前窗体
//nCmdShow: 0关闭窗口/1正常大小显示窗口/2最小化窗口/3最大化窗口
[DllImport("user32.dll")]
public static extern int ShowWindow(IntPtr hwnd, int nCmdShow); System.Threading.Mutex mutex;
void App_Startup(object sender, StartupEventArgs e)
{
bool ret;
mutex = new System.Threading.Mutex(true, "WpfDemo", out ret);
if (!ret)
{
System.Diagnostics.Process[] proc = System.Diagnostics.Process.GetProcessesByName("WpfDemo");
foreach (System.Diagnostics.Process p in proc)
{
SetForegroundWindow(p.MainWindowHandle);
ShowWindow(p.MainWindowHandle, );
NoSecond.SendMessage(p.MainWindowHandle);
}
Environment.Exit();
}
}
#endregion

NoSecond.cs

     /// <summary>
/// 禁止程序二次启动
/// </summary>
public class WPFNoSecond
{
public const int NoSecond_DATA = 0x004A;
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage
(
IntPtr hWnd, //目标窗体句柄
int Msg, //WM_COPYDATA
int wParam, //自定义数值
ref CopyDataStruct lParam //结构体
);
[StructLayout(LayoutKind.Sequential)]
public struct CopyDataStruct
{
public IntPtr dwData;
public int cbData;//字符串长度
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;//字符串
} public static void SendMessage(IntPtr thisIntPtr)
{
IntPtr xmlIntPt = new IntPtr(GetIntPtr());
if (xmlIntPt != IntPtr.Zero || thisIntPtr != IntPtr.Zero)
{
CopyDataStruct cds;
cds.dwData = IntPtr.Zero;
cds.lpData = "";
cds.cbData = ;//注意:长度为字节数
int fromWindowHandler = ;// 消息来源窗体
SendMessage(thisIntPtr.ToInt32() == ? xmlIntPt : thisIntPtr, NoSecond_DATA, fromWindowHandler, ref cds);
}
} #region 窗体句柄指针
static string _IntPtrDataDic = AppDomain.CurrentDomain.BaseDirectory + "/XML/";
static string _IntPtrDataName = "Data.xml";
static void intPtrDataExists()
{
try
{
if (!System.IO.File.Exists(_IntPtrDataDic))
{
if (!Directory.Exists(_IntPtrDataDic)) { Directory.CreateDirectory(_IntPtrDataDic); }
XmlDocument doc = new XmlDocument();
doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", ""));
XmlElement root = doc.CreateElement("Root");
root.InnerText = "";
doc.AppendChild(root);
doc.Save(_IntPtrDataDic);
}
}
catch (Exception) { }
}
static int GetIntPtr()
{
intPtrDataExists();
XDocument xml = XDocument.Load(_IntPtrDataDic + _IntPtrDataName);
XElement xmlRoot = xml.Root;
return Convert.ToInt32(xmlRoot.Value);
}
public static void SetIntPtr(string intPtr)
{
intPtrDataExists();
XDocument xml = XDocument.Load(_IntPtrDataDic + _IntPtrDataName);
XElement xmlRoot = xml.Root;
xmlRoot.Value = intPtr;
xml.Save(_IntPtrDataDic + _IntPtrDataName);
}
#endregion
}

Window.cs

         #region 禁止二次启动
private void Window_SourceInitialized(object sender, EventArgs e)
{
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
if (source == null) { throw new Exception("Cannot get HwndSource instance."); }
source.AddHook(new HwndSourceHook(this.WndProc));
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
try
{
switch (msg)
{
case WPFNoSecond.NoSecond_DATA:
this.Show();
break;
}
}
catch (Exception) { }
return IntPtr.Zero;
}
#endregion
//最小化到托盘
private void Window_Min(object sender, RoutedEventArgs e)
{
//存储当前窗体句柄
WPFNoSecond.SetIntPtr(new WindowInteropHelper(this).Handle.ToString());
}

WPF-禁止二次启动的更多相关文章

  1. 问题-[delphi2007、2010]无法二次启动,报EditorLineEnds.ttr被占用,进程一直有bds.exe?

    问题现象:delphi2007.2010无法二次启动,报EditorLineEnds.ttr被占用,而且进程中一直有bds.exe的进程? 问题原因:问题处理:方法一:可能是系统更新的东东造在的.KB ...

  2. WPF 开发自动开机启动程序

    原文:WPF 开发自动开机启动程序 本文告诉大家如何在 WPF 开发一个可以自动启动的程序 本文使用的自动开机启动方法是通过快捷方式放在启动文件夹的方式. 创建快捷方式 /// <summary ...

  3. WPF应用程序的启动画面[Splash Screen本质分析]

    原文:WPF应用程序的启动画面[Splash Screen本质分析] 不经意间发现了wpf的这个小玩意,感觉蛮有意思的.我在项目中添加了一张图片 如图: wpf-1.JPG(10.73 K) 2010 ...

  4. WPF属性(二)附加属性

    原文:WPF属性(二)附加属性 附加属性是说一个属性本来不属于某个对象,但由于某种需求而被后来附加上,也就是把对象放入一个特定环境后对象才具有的属性就称为附加属性,附加属性的作用就是将属性与数据类型解 ...

  5. Caddy源码阅读(二)启动流程与 Event 事件通知

    Caddy源码阅读(二)启动流程与 Event 事件通知 Preface Caddy 是 Go 语言构建的轻量配置化服务器.https://github.com/caddyserver/caddy C ...

  6. [WPF]WPF设置单实例启动

    WPF设置单实例启动 使用Mutex设置单实例启动 using System; using System.Threading; using System.Windows; namespace Test ...

  7. [Tomcat 源码分析系列] (二) : Tomcat 启动脚本-catalina.bat

    概述 Tomcat 的三个最重要的启动脚本: startup.bat catalina.bat setclasspath.bat 上一篇咱们分析了 startup.bat 脚本 这一篇咱们来分析 ca ...

  8. WPF的二维绘图(二)——几何图形Geometry

    在WPF的DrawingContext对象中,提供了基本的绘制椭圆和矩形的API:DrawEllipse和DrawRectangle.但是,这些是远远不够用的,我们在日常应用中,更多的是使用DrawG ...

  9. 禁止Visual Studio启动时自动连接TFS服务器

    在默认设置情况下,Visual Studio启动时,会自动连接上次打开过的TFS服务器.这种设计能够提高开发人员的工作效率,避免每次手动连接TFS服务器. 但是在某些情景中,也会给人造成不必要的麻烦, ...

随机推荐

  1. mysql使用load导入txt文件所遇到的问题及解决方法

    导入txt文件,有导入向导这种方式: 另外可以使用load的方式导入.最开始使用以下代码插入: load data local infile 'F:\\Data\\predict_data.txt' ...

  2. Python之Web框架

    Python之Web框架: 一.  Web框架的本质: 对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. #!/usr/bin/env pyth ...

  3. gdb 调试多线程

    基本i threads 等操作略过,只谈线程同步.异步控制: 先点到,gdb attach到主线程t1 时,所有线程都会停止,所谓同步异步效果,是指在apply continue到所有线程之后, 再切 ...

  4. 关于display:none 和visibility:hidden 的区别

    1.占据空间 :none 隐藏后不占据空间 visibility占据空间 2.回流与渲染:none产生回流与渲染 ? 可以通过oprea中的Profiler 工具测试. 关于回流的详细介绍:http: ...

  5. 查看机器上安装的jdk能支持多大内存

    命令:java -Xmx1024m -version C:\Users\maite>java -Xmx1024m -version java version "1.8.0_31&quo ...

  6. 使用Spring Task轻松完成定时任务

    一.背景 最近项目中需要使用到定时任务进行库存占用释放的需求,就总结了如何使用Spring Task进行简单配置完成该需求,本文介绍Spring3.0以后自定义开发的定时任务工具, spring ta ...

  7. 泛型T的类型获取

    T.getClass()或者T.class都是非法的,因为T是泛型变量. 由于一个类的类型是什么是在编译期处理的,故不能在运行时直接在Base里得到T的实际类型. /** * 可以在service层直 ...

  8. 51node1264(判断线段相交)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1264 题意:中文题诶- 思路:对于直线a1a2, b1b2, ...

  9. 【转】PHP的Trait 特性

    Trait是在PHP5.4中加入的,它既不是接口也不是类.主要是为了解决单继承语言的限制.是PHP多重继承的一种解决方案.例如,需要同时继承两个 Abstract Class, 这将会是件很麻烦的事情 ...

  10. 联想笔记本如何开启笔记本的VT-x虚拟化技术功能

    虚拟化技术支持,需几个方面的条件支持:芯片组自身支持.BIOS提供支持.处理器自身支持.操作系统支持. 操作系统方面,主流操作系统均支持VMM管理,因此无需考虑. 而芯片组方面,从Intel 945( ...