CSDN-CSDN社区-.NET技术-C#

收藏 WinForm 只允许一个实例运行的问题[问题点数:20,无满意答案结帖,结帖人:ShinyWong]

楼主发表于:2009-01-09 21:23:07
程序只允许一个实例运行, 就是查找之前运行的实例,
如果存在, 就 ShowWindow 以及 SetForegroundWindow.

不过我遇到一个问题, 就是如果程序有一个模式窗口 (Modal dialog) 在显示,
这时如果将这个 Process 的 MainWindowHandle SetForegroundWindow 之后,
本来不应该获得焦点的主窗体由于窗体前置而获得了键盘输入焦点 (不过鼠标不行).

现在就可以用 Tab 键改变焦点, Enter 键输入 (不过对 Button 来说空格键无效), 菜单也可以用 Alt 键激活.

这样, 程序就可能出现不可预知的错误, 因为程序的逻辑基本上会被完全搞乱 (如果模式窗体比较多的话更糟).

发现很多软件都有这个问题, 比如 Windows Live Messenger, Maxthon (如果只允许一个实例的话).

不知道怎样才能避免这样的问题? 谢谢.
回复次数:3
  • tiger999用户头像
  • tiger999
  • (不吃肉的老虎)
  • 等 级:
#1楼 得分:0回复于:2009-01-09 23:15:55

在你的程序中建立一个互斥锁。

C# code
static void Main(string[] args) { bool createNew; Mutex m = new Mutex(false, "MyApp", out createNew); if (!createNew) { //已经有一个实例在运行了 } }
  • wangping_li用户头像
  • wangping_li
  • (总有一天,我星球上的人会来接我)
  • 等 级:
#2楼 得分:0回复于:2009-01-10 01:23:05
C# code
using System; using System.Windows.Forms; using System.Threading; class App : Form { Mutex mutex; App() { Text = "Single Instance!"; mutex = new Mutex(false, "SINGLE_INSTANCE_MUTEX"); if (!mutex.WaitOne(0, false)) { mutex.Close(); mutex = null; } } protected override void Dispose(bool disposing) { if (disposing) mutex.ReleaseMutex(); base.Dispose(disposing); } static void Main() { App app = new App(); if (app.mutex != null) Application.Run(app); else MessageBox.Show("Instance already running"); } }


http://blog.csdn.net/ismycxp/archive/2008/02/01/2076546.aspx
#3楼 得分:0回复于:2009-01-10 12:33:36
我不是问怎么样实现只运行以一个实例, 这个我知道. (为什么经常在 CSDN 上提问都是答非所问, 呵呵.)

我是问将之前的实例 Activate 后, 模式窗口的父窗体 (也就是程序的主窗体) 获得键盘焦点的问题, 照理说不应该获得焦点的.

当然, 给一个 MessageBox 说已经有一个实例在运行也可以, 不过用户体验太不好了.
相关问题
请问:怎样让系统中同一时刻只允许一个winform实例运行。 .NET技术/ C# ...
难倒我的.net问题:.net中如何在IIS服务器端打开一个有winform界面的 ...
.net winform 超级疑惑的问题高手来看看.NET技术/ C# - CSDN社区 ...
请问在C#中,如何设置一个子窗体只能打开一个实例.NET技术/ C# - CSDN ...
webForm(b/s) vs winForm(c/s), 谁是将来的流行? .NET技术/ C# - CSDN ...
WinForm嵌入WebForm中,怎么进行数据库操作(遇到权限问题) .NET技术 ...