WPF-禁止二次启动
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-禁止二次启动的更多相关文章
- 问题-[delphi2007、2010]无法二次启动,报EditorLineEnds.ttr被占用,进程一直有bds.exe?
问题现象:delphi2007.2010无法二次启动,报EditorLineEnds.ttr被占用,而且进程中一直有bds.exe的进程? 问题原因:问题处理:方法一:可能是系统更新的东东造在的.KB ...
- WPF 开发自动开机启动程序
原文:WPF 开发自动开机启动程序 本文告诉大家如何在 WPF 开发一个可以自动启动的程序 本文使用的自动开机启动方法是通过快捷方式放在启动文件夹的方式. 创建快捷方式 /// <summary ...
- WPF应用程序的启动画面[Splash Screen本质分析]
原文:WPF应用程序的启动画面[Splash Screen本质分析] 不经意间发现了wpf的这个小玩意,感觉蛮有意思的.我在项目中添加了一张图片 如图: wpf-1.JPG(10.73 K) 2010 ...
- WPF属性(二)附加属性
原文:WPF属性(二)附加属性 附加属性是说一个属性本来不属于某个对象,但由于某种需求而被后来附加上,也就是把对象放入一个特定环境后对象才具有的属性就称为附加属性,附加属性的作用就是将属性与数据类型解 ...
- Caddy源码阅读(二)启动流程与 Event 事件通知
Caddy源码阅读(二)启动流程与 Event 事件通知 Preface Caddy 是 Go 语言构建的轻量配置化服务器.https://github.com/caddyserver/caddy C ...
- [WPF]WPF设置单实例启动
WPF设置单实例启动 使用Mutex设置单实例启动 using System; using System.Threading; using System.Windows; namespace Test ...
- [Tomcat 源码分析系列] (二) : Tomcat 启动脚本-catalina.bat
概述 Tomcat 的三个最重要的启动脚本: startup.bat catalina.bat setclasspath.bat 上一篇咱们分析了 startup.bat 脚本 这一篇咱们来分析 ca ...
- WPF的二维绘图(二)——几何图形Geometry
在WPF的DrawingContext对象中,提供了基本的绘制椭圆和矩形的API:DrawEllipse和DrawRectangle.但是,这些是远远不够用的,我们在日常应用中,更多的是使用DrawG ...
- 禁止Visual Studio启动时自动连接TFS服务器
在默认设置情况下,Visual Studio启动时,会自动连接上次打开过的TFS服务器.这种设计能够提高开发人员的工作效率,避免每次手动连接TFS服务器. 但是在某些情景中,也会给人造成不必要的麻烦, ...
随机推荐
- 用遗传算法GA改进CloudSim自带的资源调度策略
首先理解云计算里,资源调度的含义: 看了很多云计算资源调度和任务调度方面的论文,发现很多情况下这两者的意义是相同的,不知道这两者是同一件事的不同表述还是我没分清吧,任务调度或者资源调度大概就是讲这样一 ...
- DNS解析过程详解
先说一下DNS的几个基本概念: 一. 根域 就是所谓的“.”,其实我们的网址www.baidu.com在配置当中应该是www.baidu.com.(最后有一点),一般我们在浏览器里输入时会省略后面的点 ...
- js中bind、call、apply函数的用法
最近一直在用 js 写游戏服务器,我也接触 js 时间不长,大学的时候用 js 做过一个 H3C 的 web的项目,然后在腾讯实习的时候用 js 写过一些奇怪的程序,自己也用 js 写过几个的网站.但 ...
- CentOS7下安装配置MariaDB
参考: http://www.2cto.com/os/201504/394141.html http://outofmemory.cn/code-snippet/2533/mysql-create-d ...
- IDEA 配置 tomcat的数据源
1.F4打开module setting面板,找到facets 配置项,这个配置项非常重要,里面可配置tomcat加载的web.xml和context.xml文件所在的路径,部署的时候IDEA会自动读 ...
- iOS 对象的内存管理细节
通过类创建对象 1.创建对象时,开辟存储空间,通过new方法创建的对象会在 堆 内存中开辟一块存储空间 2初始化所有属性都在堆内存中完成 3.返回值真地址,指针在栈内存中,指针指向的地址是堆里创建对象 ...
- I/O 函数总结
经过一段时间的学习,发现字符处理时或者文件处理时,经常需要进行输入(读入)和输出,而可供选择的函数很多,现在反而容易搞混淆,下面就对常用的7个 输入输出函数 进行总结和比较,以便于区分和熟练掌握. 标 ...
- 在Eclipse中集成Ant配置
提要:本文将向你展示如何使用Eclipse设置为Ant所用的属性值和环境变量,并简要分析如何配置Ant编辑器以便从Eclipse内部操作Ant文件. 一. 修改Ant Classpath 在使用一个可 ...
- Sql Server本地高版本备份数据备份至远程低版本数据库方法
想要将Sqlserver高版本备份的数据还原到低版本SqlServer2008R2上去,但是这在SqlServer中是没法直接还原数据库的,通过以下方法可以顺利还原. 通过高版本生成sql脚本在低版本 ...
- 从SQLite获取数据完成一个产品信息展示
在ios实际开发当中,我们常常用到Core Data做为数据储存首选.但在处理一些大量复杂的数据值且数据之间相互关联的时候,这就不得不使用关系型数据库来实现.例如一个导航程序,自身应该包含大量的地图自 ...