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. UML类图符号 各种关系说明以及举例

    UML中描述对象和类之间相互关系的方式包括:依赖,关联,聚合,组合,泛化,实现等. 表示关系的强弱:组合>聚合>关联>依赖 相互间关系 聚合是表明对象之间的整体与部分关系的关联,而组 ...

  2. Android Studio插件:GsonFromat

    这个Android Studio插件可以根据JSONObject格式的字符串,自动生成实体类参数. 具体见:https://github.com/zzz40500/GsonFormat

  3. Ubuntu14.04源

    Ubuntu14.04源:   来源: http://wiki.ubuntu.org.cn/Qref/Source (包含15.04.14.10.14.04.12.04.10.04的源)     Ub ...

  4. tmux常用快捷键

    首先输入命令开始. $ tmux 然后,基本组合 Ctrl+b(同时按下ctrl和b),按完松开 松开后,按%(即同时按下shift和5),是水平分割 按“(即同时按shift和'),是纵向分割 按上 ...

  5. Android 获得AndroidManifest文件里自定义的meta标签内容

    try { ApplicationInfo appInfo= this.getPackageManager().getApplicationInfo(getPackageName(),PackageM ...

  6. DevExpress 隐藏Ribbon中barbuttonItem的SuperTip(2)

    在form界面增加 toolTipController 工具 然后将 ribbonControl.ToolTipController 的属性设置成 toolTipController toolTipC ...

  7. 在CentOS 7.2下升级gcc编译器的版本

    默认情况下,CentOS 7.2预装的gcc版本是4.8.x,通过执行命令 gcc -v 可以看到,一般情况下这个版本的编译器已经满足需要了,但是某些特殊的时候为了支持C++更高的特性,需要对gcc编 ...

  8. JSP复习整理(五)JavaBean生命周期

    一.创建一个JavaBean UserBean.java package jsp.test; public class UserBean { private String userName; priv ...

  9. j嵌入式f_os之定时管理

    /* * jf_timer.h * * Created on: Aug 20, 2016 * Author: lort */ #ifndef JF_OS_JF_TIMER_H_ #define JF_ ...

  10. java.io.Serializable 序列化接口

    什么是序列化.反序列化? Serialization(序列化)是一种将对象以一连串的字节描述的过程: 反序列化deserialization是一种将这些字节重建成一个对象的过程. 序列化通俗一点说就是 ...