标签:style c class blog code java
在应用程序安装之后,单击一次快捷方式,就运行一个程序实例,对于资源独占型程序来说,这样是不可以的,比如该程序使用了当前系统的某个端口,当同样的程序再次运行,再次试图占用同一个端口次,会提示“端口已经被占用的”异常。如此,必须在启动应用程序时,必须判断该程序是否已经有一个实例在运行。下面这个类中先判断该程序的实例有没有在运行,使用线程同步类EventWaitHandle(Boolean, EventResetMode, String)及注册正在等待 WaitHandle 的委托方法RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int64, Boolean)来进行线程间同步。
public class WpfSingleInstance
{
public static Window
handelWin
{
private
get;
set;
}
private static bool
findIfAlreadyRun()
{
try
{
Process current =
Process.GetCurrentProcess();
Process[] processes =
Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName);
foreach (Process process in
processes)
{
if (process.Id !=
current.Id)
{
if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") ==
current.MainModule.FileName)
{
return
true;
}
}
}
}
catch (Exception
ex)
{
new
SaveExceptionInfo().SaveLogAsTXTInfoex(ex.Message);
}
return
false;
}
//线程间同步
internal static void Make(String name, Application
app)
{
EventWaitHandle eventWaitHandle =
null;
String eventName = Environment.MachineName + "-" +
Environment.CurrentDirectory.Replace(‘\\‘, ‘-‘) + "-" +
name;
bool isFirstInstance =
!findIfAlreadyRun();
if
(isFirstInstance)
{
try
{
//当前程序没有实例在运行时
eventWaitHandle = new
EventWaitHandle(
false,
EventResetMode.AutoReset,
eventName);
ThreadPool.RegisterWaitForSingleObject(eventWaitHandle,
waitOrTimerCallback,app, Timeout.Infinite,
false);
}
catch (Exception
ex)
{
new
SaveExceptionInfo().SaveLogAsTXTInfoex(ex.Message);
}
finally
{
eventWaitHandle.Close();
}
}
else
{
try
{
//当前程序已经有了实例在运行时,打开已经运行的实例,而不是从新运行一个
eventWaitHandle =
EventWaitHandle.OpenExisting(eventName);
//唤醒已经运行的实例
eventWaitHandle.Set();
// For that exit no
interceptions
Environment.Exit(0);
}
catch (Exception
ex)
{
new
SaveExceptionInfo().SaveLogAsTXTInfoex(ex.Message);
}
}
}
///
< summary>
///
已经在运行的程序实例在被唤醒时的需要执行的代码
///
< /summary>
/// <param
name="state"></param>
/// <param
name="timedOut"></param>
private static void waitOrTimerCallback(Object state, Boolean
timedOut)
{
Application app =
(Application)state;
app.Dispatcher.BeginInvoke(new
activate(delegate()
{
//
Application.Current.MainWindow.Activate();
//if (handelWin !=
null)
//{
//
handelWin.Show();
//}
//else
//{
Application.Current.MainWindow.Activate();
//}
}),
null);
}
private delegate void activate();
}
在App.xaml.cs中重载OnStartup方法,调用WpfSingleInstance
protected override void OnStartup(StartupEventArgs e) { WpfSingleInstance.Make("FilePullar", this); base.OnStartup(e); }
这样单击已运行程序的快捷方式时,会弹出已经在运行的应用程序的界面,而不是重新打开应用程序的实例。
多次单击快捷方式,只运行一个程序实例,布布扣,bubuko.com
标签:style c class blog code java
原文地址:http://www.cnblogs.com/goxmpx/p/3752481.html