如何禁止桌面程序重复启动
许多程序只允许启动单个实例,比如我们常用的MSN、OUTLOOK等等。单实例有很多好处,其中最重要一点即是安全。想像一下多人同时修改同一文件的危险,就如我们在J2EE应用程序中所做的那样,要尽可能考虑到多用户同时访问的问题。
前些日子用SWING为朋友写了一个程序,其中就有不可同时启动多个系统实例的要求。由于没有一个好的思路,所以走了很多弯路。现在终于解决了,积累了一些心德想与大家分享。
初遇该问题时,我首先想到的是进程。当程序启动时判断操作系统中是否存在该进程,如果存在就退出启动,否则启动程序。这个方法在VB或C语言中可以通过调用WIN32 API来实现。在JAVA中,要想实现该方法或许还要借助C的力量。(对于JAVA如何捕获进程,还请批评指正。)
放弃了第一种方法,想到了弱智的方法–配置文件。当系统第一次启动时将标识设置为启动中,退出时将标识设置为未启动。但很快就发现,当非法关闭程序(比如关机时未及时关闭程序)后,我们的程序便永远长眠了。
其实,在该程序中,最限制我们思路的便是"单机版"这三个字。它给我们的印象是仅供一台机器单独使用,与网络无关的。因此,我们很难将思路整理到服务器与客户机中去。但要解决该问题恰恰要用到服务器与客户机的概念。想像一下我们平时启动电脑的步骤,首先按下加电,有了电,电脑才能启动。没错,只有当电脑未加电,也就是说当我们首次启动电脑时才会做这个动作,而且这个动作在一段时间内只会做一次。若要重新加电,就必需先断电。现在回到我们的程序,有了这个思路,留给我们的问题就是谁来充当电的角色呢?没错,就是之前提到过的服务器。程序首次启动时首先连接指定端口的服务器,发现服务器并未启动,于是启动服务器,启动程序。当程序复数启动时,再次连接服务器,这时发现服务器已经启动了,于是就终止启动。代码如下:
- package com.mxjava;
- public class Console {
- /** 端口号 */
- private static int iPort = 50000;
- /** 主窗口 */
- JFrame frame = null;
- /**
- * 系统入口
- *
- * @param String[]
- * args
- */
- public static void main(String[] args) throws Exception {
- Socket socket = null; // 客户端连接器
- Thread thread = null; // 启动服务器的线程
- try {
- // 连接服务器
- // 如果服务器未启动则抛异常
- (socket = new Socket("localhost", iPort)).close();
- // 如果服务器已经启动则退出系统
- System.exit(0);
- } catch (Exception e) {
- }// 未做处理
- // 如果服务器未启动则在新的线程中启动服务器
- (thread = new Thread(new Server())).setDaemon(true);
- // 开始线程
- thread.start();
- // 启动主程序
- frame = new JFrame("学海无涯");
- frame.setVisible(true);
- }
- /**
- * 端口监听服务器端运行
- *
- * @author hiswing
- */
- static class Server implements Runnable {
- public final void run() {
- ServerSocket serversocket = null;
- // 查找没有占用的端口
- while (iPort < 60000) {
- try {
- serversocket = new ServerSocket(iPort);
- } catch (Exception ex) {
- iPort++;
- }
- break;
- }
- try {
- do {
- // 监听客户端是否有连接
- serversocket.accept();
- // 窗口在任务栏闪动
- if (frame.getExtendedState() == 1) {
- frame.setExtendedState(0);
- }
- if (frame.getExtendedState() != 1) {
- frame.toFront();
- frame.requestFocus();
- frame.repaint();
- }
- } while (true);
- } catch (Exception ex) {
- // 不做处理
- }
- }
- }
- }
关键字: Swing