当前位置: MXJAVA > JAVA开发 > 文章正文

如何禁止桌面程序重复启动

发表于 2004-11-24 | 阅读 67 views

  许多程序只允许启动单个实例,比如我们常用的MSN、OUTLOOK等等。单实例有很多好处,其中最重要一点即是安全。想像一下多人同时修改同一文件的危险,就如我们在J2EE应用程序中所做的那样,要尽可能考虑到多用户同时访问的问题。

前些日子用SWING为朋友写了一个程序,其中就有不可同时启动多个系统实例的要求。由于没有一个好的思路,所以走了很多弯路。现在终于解决了,积累了一些心德想与大家分享。

初遇该问题时,我首先想到的是进程。当程序启动时判断操作系统中是否存在该进程,如果存在就退出启动,否则启动程序。这个方法在VB或C语言中可以通过调用WIN32 API来实现。在JAVA中,要想实现该方法或许还要借助C的力量。(对于JAVA如何捕获进程,还请批评指正。)

放弃了第一种方法,想到了弱智的方法–配置文件。当系统第一次启动时将标识设置为启动中,退出时将标识设置为未启动。但很快就发现,当非法关闭程序(比如关机时未及时关闭程序)后,我们的程序便永远长眠了。

其实,在该程序中,最限制我们思路的便是"单机版"这三个字。它给我们的印象是仅供一台机器单独使用,与网络无关的。因此,我们很难将思路整理到服务器与客户机中去。但要解决该问题恰恰要用到服务器与客户机的概念。想像一下我们平时启动电脑的步骤,首先按下加电,有了电,电脑才能启动。没错,只有当电脑未加电,也就是说当我们首次启动电脑时才会做这个动作,而且这个动作在一段时间内只会做一次。若要重新加电,就必需先断电。现在回到我们的程序,有了这个思路,留给我们的问题就是谁来充当电的角色呢?没错,就是之前提到过的服务器。程序首次启动时首先连接指定端口的服务器,发现服务器并未启动,于是启动服务器,启动程序。当程序复数启动时,再次连接服务器,这时发现服务器已经启动了,于是就终止启动。代码如下:

  1. package com.mxjava; 
  2.  
  3. public class Console { 
  4.     /** 端口号 */ 
  5.     private static int iPort = 50000
  6.  
  7.     /** 主窗口 */ 
  8.     JFrame frame = null
  9.  
  10.     /** 
  11.      * 系统入口 
  12.      *  
  13.      * @param String[] 
  14.      *            args 
  15.      */ 
  16.     public static void main(String[] args) throws Exception { 
  17.         Socket socket = null// 客户端连接器 
  18.         Thread thread = null// 启动服务器的线程 
  19.  
  20.         try { 
  21.             // 连接服务器 
  22.             // 如果服务器未启动则抛异常 
  23.             (socket = new Socket("localhost", iPort)).close(); 
  24.             // 如果服务器已经启动则退出系统 
  25.             System.exit(0); 
  26.         } catch (Exception e) { 
  27.         }// 未做处理 
  28.  
  29.         // 如果服务器未启动则在新的线程中启动服务器 
  30.         (thread = new Thread(new Server())).setDaemon(true); 
  31.         // 开始线程 
  32.         thread.start(); 
  33.  
  34.         // 启动主程序 
  35.         frame = new JFrame("学海无涯"); 
  36.         frame.setVisible(true); 
  37.     } 
  38.  
  39.     /** 
  40.      * 端口监听服务器端运行 
  41.      *  
  42.      * @author hiswing 
  43.      */ 
  44.     static class Server implements Runnable { 
  45.         public final void run() { 
  46.             ServerSocket serversocket = null
  47.  
  48.             // 查找没有占用的端口 
  49.             while (iPort < 60000) { 
  50.                 try { 
  51.                     serversocket = new ServerSocket(iPort); 
  52.                 } catch (Exception ex) { 
  53.                     iPort++; 
  54.                 } 
  55.                 break
  56.             } 
  57.             try { 
  58.                 do { 
  59.                     // 监听客户端是否有连接 
  60.                     serversocket.accept(); 
  61.  
  62.                     // 窗口在任务栏闪动 
  63.                     if (frame.getExtendedState() == 1) { 
  64.                         frame.setExtendedState(0); 
  65.                     } 
  66.                     if (frame.getExtendedState() != 1) { 
  67.                         frame.toFront(); 
  68.                         frame.requestFocus(); 
  69.                         frame.repaint(); 
  70.                     } 
  71.                 } while (true); 
  72.             } catch (Exception ex) { 
  73.                 // 不做处理 
  74.             } 
  75.         } 
  76.     } 

 

Del.icio.us Google书签 Digg Live Bookmark Technorati Furl Yahoo书签 Facebook 百度搜藏 新浪ViVi 365Key网摘 天极网摘 和讯网摘 博拉网 POCO网摘 添加到饭否 QQ书签 Digbuzz我挖网 关键字:
喜欢MXJAVA的文章,那就通过 RSS Feed 功能订阅阅读吧!

我要评论

*

* 绝不会泄露



返回首页 | 关于我们 | 联系我们 | 广告合作 | 友情链接 | 版权声明