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服务器. 但是在某些情景中,也会给人造成不必要的麻烦, ...
随机推荐
- Moving Average from Data Stream
Given a stream of integers and a window size, calculate the moving average of all integers in the sl ...
- [正则表达式]PCRE环视功能
设想一下这个问题,假设为了方便长串数字的阅读性,需要为其添加逗号作为分隔,需要怎么做呢? 2569836495 => 2,569,836,495 正则表达式的匹配通常是从左往右的,这导致无法使用 ...
- iOS web remote debug 正确的姿势
在使用iOS Remote debug需要做以下准备 1. iOS devices 开启java script and web inspector 开启方式如下: 2. mac OS 自带的Safar ...
- WinForm跨窗体传值
1.另一窗体建公共变量listdataRow public List<DataGridViewRow> listdataRow = new List<DataGridViewRow& ...
- Wakez计算与压缩的思考
大部分人认为,比尔盖茨在1981年说过这样一句话:640K ought to be enough for anybody.(640个kB对任何人来说都应该足够了).不过后来比尔盖茨否认自己说过这句话. ...
- 等差数列(bzoj 3357)
Description 约翰发现奶牛经常排成等差数列的号码.他看到五头牛排成这样的序号:"1,4,3,5,7" 很容易看出"1,3,5,7"是等差数列. ...
- CSS网页制作常用标签
做了一个简单的网页,从布局到加内容,遇到了很多小问题.很多标签和属性都不会用或者忘记了.所以以此记录一下. 一.如何将边框四角变圆?(或做一个圆形) 顾名思义,如果要更改边框的角需要用到边框(bord ...
- linux ps命令,查看进程cpu和内存占用率排序(转)
使用以下命令查看: ps -aux | sort -k4,4n ps auxw --sort=rss ps auxw --sort=%cpu linux 下的ps命令 %CPU 进程的cpu占用率 % ...
- display:table-cell的应用
一.display:table-cell属性简述 display:table-cell属性指让标签元素以表格单元格的形式呈现,类似于td标签.目前IE8+以及其他现代浏览器都是支持此属性的,但是IE6 ...
- 新浪云SAE搭建python环境 问题拾遗
1.python程序部署到sae上需要做的改动 在线上需要转换成wsgi的形式运行python程序. sae中运行python程序需要指定一个函数为入口函数. application = sae.cr ...