Abrir somente uma Istancia

4 respostas
R

Quero que, depois do sistema pronto e funcionando, que o usuário, caso já tenha uma instância do programa aberta no SO, não consiga abrir outras.
Tem como fazer isso.

4 Respostas

articof

use o Pattern Singleton

Marky.Vasconcelos

Isso só evita abri duas janelas no mesmo programa e não dois programas por maquina.

Da uma procurada pelo fórum que essa questão já foi discutida aqui antes e já tem algumas soluções.

EderBaum
/*
 * MultipleInstanceChecker.java
 *
 * Created on 2 de Março de 2007, 16:53
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

import java.awt.Window;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Helper class to avoid running more than one concurrent instance of
 * a Java program.
 *
 * <h3>Rationale</h3>
 * With some applications it may be useless or even dangerous to run
 * more than one instance at the same time.
 * This class helps a Java application to determine if another instance
 * is running already.
 * It does so by trying to reserve a server socket for a given port.
 * If the server socket can be reserved, this instance is the first one.
 * Otherwise a user-defined byte signature is sent to the running
 * instance, which can then perform some action (e.g. bringing its
 * own window to the front of the desktop).
 *
 * <h3>Usage</h3>
 * public class MultipleInstanceTest {
 *     public static void main(String[] args) {
 *         final int PORT = 44593;
 *         final byte[] SIGNATURE = new byte[] {0x34, 0x55, 0x7c, 0x03, 0x64, 0x22, 0x1e, 0x4a};
 *         JFrame frame = new JFrame("MultipleInstanceChecker test app");
 *        JLabel label = new JLabel("Starting up...");
 *         frame.add(label);
 *         frame.pack();
 *         frame.setVisible(true);
 *         MultipleInstanceChecker checker = new MultipleInstanceChecker(SIGNATURE, PORT, frame);
 *         int result = checker.check();
 *        String message = null;
 *        switch(result) {
 *            case(MultipleInstanceChecker.STATUS_FIRST_INSTANCE):
 *             {
 *                 message = "First instance.";
 *                 break;
 *             }
 *            case(MultipleInstanceChecker.STATUS_INSTANCE_EXISTS):
 *             {
 *                 message = "Not the first instance.";
 *                 break;
 *             }
 *             case(MultipleInstanceChecker.STATUS_SECURITY_EXCEPTION):
 *             {
 *                 message = "Some security exception. Port in use by another application?";
 *                 break;
 *             }
 *         }
 *        label.setText(message);
 *        
 *         // in a real application: add a call to
 *         // checker.shutdownServerSocketThread
 *        // in the application's "window close" code
 *     }
 * }
 *
 * @author Marco Schmidt
 */
public class MultipleInstanceChecker {
    /** Length of byte[] signature in bytes. */
    public static final int SIGNATURE_LENGTH = 8;
    
    // result values for {@link #check()}.
    public static final int STATUS_FIRST_INSTANCE = 1;
    public static final int STATUS_INSTANCE_EXISTS = 2;
    public static final int STATUS_SECURITY_EXCEPTION = 3;
    
    private byte[] signature;
    private int socketPort;
    private ServerSocket serverSocket;
    private Window window;
    private boolean shutdown;
    
    /**
     * Create a MultipleInstanceChecker.
     * @param applicationSignature a byte array of length 8 or larger
     * @param port number of the port for which a server socket is to be reserved
     */
    public MultipleInstanceChecker(byte[] applicationSignature, int port) {
        if (applicationSignature == null ||
                applicationSignature.length != SIGNATURE_LENGTH) {
            throw new IllegalArgumentException("Signature length in bytes must be " +
                    SIGNATURE_LENGTH);
        }
        signature = new byte[applicationSignature.length];
        System.arraycopy(applicationSignature, 0, signature, 0, applicationSignature.length);
        socketPort = port;
        shutdown = false;
    }
    
    public MultipleInstanceChecker(byte[] applicationSignature, int port, Window win) {
        this(applicationSignature, port);
        setWindow(win);
    }
    
    public int check() {
        try {
            serverSocket = new ServerSocket(socketPort);
            serverSocket.setSoTimeout(0);
            new Thread(
                    new Runnable() {
                public void run() {
                    while (true) {
                        Socket socket = null;
                        InputStream in = null;
                        // create a socket for incoming "call"
                        try {
                            socket = serverSocket.accept();
                        } catch (IOException ioe) {
                            continue;
                        }
                        if (shutdown) {
                            break;
                        }
                        // create InputStream to read from other process
                        try {
                            in = socket.getInputStream();
                        } catch (IOException ioe) {
                            close(socket, in);
                            continue;
                        }
                        // allocate data array
                        byte[] data = new byte[SIGNATURE_LENGTH];
                        // read SIGNATURE_LENGTH bytes from input
                        if (!readSignature(in, data)) {
                            close(socket, in);
                            continue;
                        }
                        close(socket, in);
                        boolean equal = true;
                        for (int i = 0; i < data.length; i++) {
                            if (data[i] != signature[i]) {
                                equal = false;
                                break;
                            }
                        }
                        if (equal) {
                            onRestart();
                        }
                    }
                    try {
                        serverSocket.close();
                    } catch (IOException ioe) {
                        
                    }
                }
            }
            ).start();
            return STATUS_FIRST_INSTANCE;
        } catch (IOException ioe) {
            // could not reserve server socket
            
            // try to send signature to other process, making it call
            // its onRestart method
            
            // try to get socket on that port
            Socket socket = null;
            try {
                socket = new Socket("localhost", socketPort);
            } catch (IOException ioe2) {
                return STATUS_INSTANCE_EXISTS;
            }
            
            // get stream to write to
            OutputStream out = null;
            try {
                out = socket.getOutputStream();
            } catch (IOException ioe2) {
                close(socket);
            }
            
            // write signature
            try {
                out.write(signature);
                out.flush();
            } catch (IOException ioe2) {
            }
            
            close(socket, out);
            return STATUS_INSTANCE_EXISTS;
        } catch (SecurityException se) {
            return STATUS_SECURITY_EXCEPTION;
        }
    }
    
    private void close(Socket socket) {
        if (socket != null) {
            try {
                socket.close();
            } catch (IOException ioe) {
                
            }
        }
    }
    
    private void close(Socket socket, InputStream in) {
        close(socket);
        if (in != null) {
            try {
                in.close();
            } catch (IOException ioe) {
                
            }
        }
    }
    
    private void close(Socket socket, OutputStream out) {
        close(socket);
        if (out != null) {
            try {
                out.close();
            } catch (IOException ioe) {
                
            }
        }
    }
    
    public void onRestart() {
        System.out.println("Restart detected!");
        if (window != null) {
            window.toFront();
        }
    }
    
    private boolean readSignature(InputStream in, byte[] data) {
        int index = 0;
        while (index < data.length) {
            try {
                int numRead = in.read(data, index, data.length - index);
                if (numRead > 0) {
                    index += numRead;
                }
            } catch (IOException ioe) {
                return false;
            }
        }
        return true;
    }
    
    public void setWindow(Window win) {
        window = win;
    }
    
    public void shutdownServerSocketThread() {
        // set shutdown variable
        shutdown = true;
        // make thread accept once more and then react to shutdown==true
        try {
            new Socket(serverSocket.getInetAddress(), serverSocket.getLocalPort()).close();
        } catch (IOException ioe) {
        }
    }
}
L

O teu sistema é multiusuário? Se for dá pra controlar no banco de dados, os que estão ou não logados, daí fica fácil…
daí ao abrir o sistema, verifica no banco se o usuário já está ou não logado

Criado 15 de maio de 2008
Ultima resposta 16 de mai. de 2008
Respostas 4
Participantes 5