Domanda Verificare se il programma è già in esecuzione

ZioCrick

Utente Bronze
13 Ottobre 2019
8
3
1
20
Ciao a tutti,
non so se il titolo rende l'idea ma vorrei poter eseguire un programma che prima di visualizzare l'interfaccia grafica, verifichi se esiste già un'istanza dello stesso programma in esecuzione e se esiste passi il fuoco a quell'istanza (in pratica la porti in primo piano rispetto alle altre applicazioni) e termini la sua esecuzione (quella della seconda istanza).

Possibilmente quando l'istanza in esecuzione esegue una certa operazione richiesta dall'utente, dovrebbe rendersi invisibile pur rimanendo in esecuzione, in modo che ad un seccessivo run della stessa applicazione venga semplicemente attivata l'istanza invisibile.

Quello che ho descritto l'avevo realizzato quando sviluppavo in VB6 ovviamente solo su Windows fino a XP.

L'applicazione dovrebbe essere totalmente multipiattaforma, perché ho WinXP, Win7, Win8.1, Kubuntu 14.04, Kubuntu 18.04.

Ora sto usando Netbeans (sia su Windows che su Kubuntu) come strumento di sviluppo.

Non so se mi sono spiegato.
Lo scopo è di velocizzare la comparsa del programma ogni volta che ne ho bisogno, perchè la prima attivazione è troppo lenta.

Qualcuno sa darmi indicazioni su come realizzare una cosa del genere?
 
Giusto per capire ... qualcuno, magari tra i più esperti, potrebbe gentilmente dirmi se la mia domanda è chiara, o se mancano dettagli oppure se quello che sto cercando di realizzare non è fattibile con Java?
Grazie mille.
 
Capire se c'è una sola istanza attiva non è banalissimo perché ti devi interfacciare con il sistema operativo per capire cos'altro c'è in esecuzione. In VB6 era facile perché il linguaggio è pensato per girare su un solo sistema operativo. Leggendo in giro consigliano metodi alternativi, tipo aprire un dummy socket (quando la seconda istanza proverà a riaprire la stessa porta lancerà un'eccezione) oppure scrivere un file temporaneo. In alternativa c'è un SingleInstanceService in javax, ma non più parte della JDK quindi è discutibile quanto questa soluzione sia portable.

Per portare l'istanza già aperta in primo piano e per trasformare il tuo processo in un servizio non credo che ci siano trucchetti da poter sfruttare. O trovi una classe/metodo che fa al caso tuo o non ci puoi fare niente.

Lo scopo è di velocizzare la comparsa del programma ogni volta che ne ho bisogno, perchè la prima attivazione è troppo lenta.
Considera l'ipotesi di lasciare il programma java così com'è e di farti uno script in bash (per linux) e uno in batch (per windows) che si preoccupino di lanciare quel programma java e portarlo in primo piano in caso servisse. Su linux dovrai interfacciarti con Xorg o Wayland (non so quale dei due stai usando, KDE può usarli entrambi). In Xorg solitamente si usa xdtool per questo genere di operazioni.
 
Grazie St3ve per le indicazioni.

Ok, supponiamo che io riesca, tramite socket (di cui non conosco nulla) o tramite file temporaneo, a verificare l'esistenza di un'altra istanza del programma in esecuzione.
A questo punto la difficoltà sarebbe proprio come portare in primo piano l'istanza già in esecuzione.

Considera l'ipotesi di lasciare il programma java così com'è e di farti uno script in bash (per linux) e uno in batch (per windows) che si preoccupino di lanciare quel programma java e portarlo in primo piano in caso servisse. Su linux dovrai interfacciarti con Xorg o Wayland (non so quale dei due stai usando, KDE può usarli entrambi). In Xorg solitamente si usa xdtool per questo genere di operazioni.
E qui casco come una pera cotta, perché anche di script non ne so nulla.

Tu intendi dire che da script riuscirei a verificare se esiste un'istanza già attiva del programma che sto per eseguire da script e portare quella istanza in primo piano?
 
Tu intendi dire che da script riuscirei a verificare se esiste un'istanza già attiva del programma che sto per eseguire da script e portare quella istanza in primo piano?
Io intendo che ogni tanto è meglio indagare su quale sia il best tool for the job. Se un linguaggio è estremamente portable (tipo Java, che gira anche sui frigoriferi) sarà tipicamente abbastanza slegato dal sistema operativo su cui gira. Al contrario, se un linguaggio è parte integrante di un sistema operativo, probabilmente avrà anche delle funzionalità che gli permettono di interagirci facilmente. È per questo che ciò che chiedi era molto facile in Visual Basic e non è così semplice in Java. Il mio consiglio è di non toccare il tuo programma Java e di implementare la feature di cui stai parlando (sia istanza unica che porta in primo piano) via bash e batch script.

Vedo che in bash (linux) puoi fare wmctrl -a nomeprogramma per portare un programma in primo piano. Per eseguire un programma fai ./nomeprogramma && disown. Per capire se un programma è in esecuzione puoi usare pgrep, che tra l'altro ti restituisce il pid del programma, oppure greppare direttamente da wmctrl -l (dove vedi i nomi che devi scrivere in wmctrl -a). Cerca come si fanno gli if in bash (se non sbaglio c'è pure una guida su questo forum) e hai praticamente finito la versione linux. Saranno 4-5 righe al massimo, ma bisogna sperimentare un minimo quindi non mi metto a scrivertele.
 
Caro St3ve, concordo pienamente con "lo sperimentare" ... tutto quello che ho imparato sulla programmazione (a parte l'unico esame di teoria generale ai tempi dell'università) proviene da prove, errori, smanettamenti, reset totali di pc, reinstallazioni e successivamente da indicazioni sui vari forum tecnici e qualche esempio trovato sul web da cui sono partito per sperimentare. :)
Per questo ti ringrazio per avermi chiarito il tuo pensiero e per le indicazioni sui comandi da usare in bash ... almeno ora ho una traccia su cui sperimentare ;)
 
Aggiornamento,
è passato un po di tempo perchè dopo aver provato varie alternative con gli script, come consigliato dall'amico St3ve senza successo :(, mi sono incapponito con Java ...
e dopo infinite ricerce, studio di manuali e tutorial, prove e riprove e testate contro il muro ...
usando i thread e i socket sono riuscito ad ottenere un'applicazione che al momento dell'attivazione si accorge che una precedente istanza dello stesso programma è attiva, le invia un messaggio per mandarla in primo piano e lei termina.
Funziona egregiamente sia su Windows Xp che su Kubuntu 14.04

Su Windows 8.1 invece l'applicazione ha un comportamenteo strano.
Preciso che a questa applicazione ho associato una combinazione di tasti di scelta rapida per l'attivazione:
per esempio <Ctrl><Shift><K>.

La prima attivazione la faccio con <Ctrl><Shift><K> e parte regolarmente.
La seconda attivazione, se la faccio ancora con <Ctrl><Shift><K> non succede nulla e se la prima istanza è dietro a qualche altra finestra, resta li.
Se invece attivo la seconda istanza dal menù di Start di Windows funziona correttamente, ovvero la prima istanza viene portata in primo piano e la seconda si chiude regolarmente.

Non capisco il perchè di questa differenza di comportamente in base al modo in cui la eseguo.
Qualcuno ha qualche idea?