相关文章推荐
坚韧的包子  ·  JavaScript | ...·  5 月前    · 
英姿勃勃的地瓜  ·  AttributeError: ...·  5 月前    · 
淡定的火锅  ·  如何取消 ...·  10 月前    · 
可爱的木耳  ·  groovy 字符串转json-掘金·  1 年前    · 

代码如下:

class SingletonWindow
{
//
注册附加属性
public static readonly
DependencyProperty IsEnabledProperty
=
DependencyProperty .RegisterAttached( "IsEnabled" , typeof ( bool ), typeof ( SingletonWindow ), new FrameworkPropertyMetadata (OnIsEnabledChanged));

public static void SetIsEnabled( DependencyObject element, Boolean
value)
{
element.SetValue(IsEnabledProperty,
value);
}
public static Boolean
GetIsEnabled( DependencyObject
element)
{
return ( Boolean )element.GetValue(IsEnabledProperty);
}

//
根据附加属性的返回值使能单实例模式
public static void
OnIsEnabledChanged( DependencyObject obj,
DependencyPropertyChangedEventArgs
args)
{
if (( bool )args.NewValue != true )
{
return ;
}

Process();
return ;
}

public static void Process() //
如果不适用附加属性也可以直接使用此函数
{
//
判断单实例的方式有很多,如 mutex process ,文件锁等,这里用的是 process 方式

var
process = GetRunningInstance();
if
(process != null )
{
HandleRunningInstance(process);
Environment .Exit(0);
}
}

const int
WS_SHOWNORMAL = 1;

[System.Runtime.InteropServices. DllImport ( "User32.dll" )]
static extern bool ShowWindowAsync( IntPtr hWnd, int
cmdShow);
[System.Runtime.InteropServices. DllImport ( "User32.dll" )]
static extern bool SetForegroundWindow( IntPtr
hWnd);
[System.Runtime.InteropServices. DllImport ( "user32.dll" )]
static extern bool FlashWindow( IntPtr hWnd, bool
bInvert);

static
System.Diagnostics. Process
GetRunningInstance()
{
var
current = System.Diagnostics. Process .GetCurrentProcess();
var processes = System.Diagnostics. Process .GetProcessesByName(current.ProcessName);

foreach ( var process
in processes)
{
if (process.Id !=
current.Id)
if
(System.Reflection. Assembly .GetExecutingAssembly().Location.Replace( "/" , "\\" ) ==
current.MainModule.FileName)
return process;
}
return null ;
}

static void
HandleRunningInstance(System.Diagnostics. Process instance)
{
if (instance.MainWindowHandle!= IntPtr .Zero)
{
for ( int i = 0; i
< 2;
i++)
{
FlashWindow(instance.MainWindowHandle,
500);
}

SetForegroundWindow(instance.MainWindowHandle);
ShowWindowAsync(instance.MainWindowHandle,
WS_SHOWNORMAL);
}
else
{
//else
处理有点麻烦,简化如下
MessageBox .Show( " 已经有一个实例在运行,无法启动第二个实例 " );
}
}

static void
FlashWindow( IntPtr hanlde, int interval)
{
FlashWindow(hanlde,
true );
System.Threading. Thread .Sleep(interval);
FlashWindow(hanlde,
false );
System.Threading. Thread .Sleep(interval);
}
}

代码其实很简单,前半部分是注册依赖属性,然后根据依赖属性判断是否启用单实例模式;后半部分就是一个传统的单实例模式的功能了。也就不介绍了。

使用这段代码也很简单:

Xaml方式:在主窗口的xaml文件中加入附加属性即可
< Window xmlns : src ="clr-namespace:WpfApplication1" src : SingletonWindow.IsEnabled ="true" >
  • 传统方式:直接使用代码中后半部分,和winform下没什么区别。在主窗口的构造函数里面加入这句话。
    SingletonWindow .Process();
  •