PDA

Visualizza la versione completa : [Java] Impedire aperture multiple programma


ilc0rv0
21-06-2005, 09:25
ciao a tutti, come posso impedire aperture multiple del mio programma?
Se ad esempio apro KMail (programma di posta su linux) o outlook express su windows, e premo di nuovo sull'icona ad esso associata, non mi viene aperto un altro programma, ma torna in primo piano la finestra di quello già aperto :)
penso che si debba controllare se in memoria è già caricato il programma, ma non ho la più pallida idea di come si possa fare :master: :)

HaCk88
21-06-2005, 09:46
Forse ti potrebbe servire un thread che si apre in modalità nascosta all'avvio del programma e ti segnala che il programma è già avviato :master: .
Devo essere sincero i thread non gli ho ancora studiati anzi sono arrivato proprio a questo capitolo e oggi devo iniziarli :bhò: .

:ciauz:

ilc0rv0
21-06-2005, 09:49
ho trovato questo su internet:
http://www.rgagnon.com/javadetails/java-0288.html

la questione del lock del file temporaneo sembra una buona cosa e nn si può neanche eliminare un file in uso dall'OS quindi a primo acchitto sembra valida...
voi che ne dite? :D

HaCk88
21-06-2005, 09:53
Forse quella tecnica può essere una delle tante soluzioni :)

ilc0rv0
21-06-2005, 10:25
ho leggermente modificato il codice, ora è adatto al mio scopo funziona :D

ho copiato il metodo void test(), l'ho chiamato blocca() e l'ho dichiarato private static void blocca()
cambiando:
JustOneLock ua = new JustOneLock("JustOneId");
in
Blocca ua = new Blocca("nomedelmioprogramma");

ho eliminato la parte che fa comparire i puntini in sequenza lasciando nell'else solamente System.out.println("NOT already active.");
che neanche serve quindi volendo si può cancellare tutto l'else

e l'ho incollato il tutto nella classe del mio programma dove ho il main.

nel main come prima operazione chiamo il metodo blocca() della classe Blocco.java (ho semplicemente cambiato nome al file JustOneLock.java e ho cambiato ovviamente il costruttore)

viene creato un file .tmp nella home dell'utente (chi ha linux potrebbe anteporre il "." al nome del file cosi da renderlo nascosto) ed il gioco è fatto :D



private static void blocca() {
Blocco ua = new Blocco("edicola");
if (ua.isAppActive()) {
System.out.println("Already active.");
System.exit(1);
}
else {
System.out.println("NOT already active.");
}
}




--------------------------------------
Blocco.java


import java.io.*;
import java.nio.channels.*;

public class Blocco {
private String appName;
private File file;
private FileChannel channel;
private FileLock lock;

public Blocco(String appName) {
this.appName = appName;
}

public boolean isAppActive() {
try {
file = new File(System.getProperty("user.home"), appName + ".tmp");
channel = new RandomAccessFile(file, "rw").getChannel();

try {
lock = channel.tryLock();
}
catch (OverlappingFileLockException e) {
// already locked
closeLock();
return true;
}

if (lock == null) {
closeLock();
return true;
}

Runtime.getRuntime().addShutdownHook(new Thread() {
// destroy the lock when the JVM is closing
public void run() {
closeLock();
deleteFile();
}
});
return false;
}
catch (Exception e) {
closeLock();
return true;
}
}

private void closeLock() {
try { lock.release(); }
catch (Exception e) { }
try { channel.close(); }
catch (Exception e) { }
}

private void deleteFile() {
try { file.delete(); }
catch (Exception e) { }
}
}

:ciauz: :ciauz: :ciauz:

ilc0rv0
21-06-2005, 10:37
problema, sbagliavo quando pensavo di non poter cancellare il file temporaneo dopo l'apertura del programma :(
come posso impedire la sua cancellazione?
posso fare in modo che il file sia aperto dal programma (quindi la sua eliminazione dovrebbe essere bloccata dal sistema operativo in quanto il file è usato da un processo) fino alla chiusura del programma?

krumiro
21-06-2005, 14:56
Originariamente inviato da ilc0rv0

quindi a primo acchitto sembra valida...
voi che ne dite? :D

Che succede se il PC si spegne improvvisamente? :ciauz:

LeleFT
21-06-2005, 15:05
Una soluzione più drastica, ma più semplice da portare a termine è l'utilizzo delle Socket: quando il programma parte, apro una socket in ascolto su una determinata porta. Se il programma viene riaperto, tenterà di fare la stessa cosa e solleverà una eccezione (BindException) perchè la porta è già occupata. :)


Ciao. :ciauz:

Loading