Rendere chiaro ed autoesplicativo il titolo di una discussione, diventa volte un'impresa insormontabile.
Cerco di spiegare qui quello che vorrei ottenere:
Ho terminato una parte del mio programma DomusRatio. Ho anche cristallizzato il file eseguibile (DomusRatio.Lazarus), in modo che posso avviare sempre l'attuale programma, funzionante e, poichè il mio ambiente Linux è avviabile in DualBoot (Ubuntu e Fedora), ho creato due file DomusRatio.desktop, uno in ciascun ambiente operativo, in modo che posso lanciare quell'eseguibile sempre, a prescindere se sto usando Fedora o Ubuntu.
Nella mia logica, fin qui funziona tutto bene.
Ho scoperto però che occorrerebbero le seguenti protezioni:
a)- Avviare solo una volta l'eseguibile, cioè, impedire che, dopo avere avviato l'eseguibile la prima volta, se mentre esso è attivo, clicco di nuovo sull'icona, si avvii una seconda volta, poi una terza e . . . così via fino ad avere attive, tutte in esecuzione, n copie dello stesso programma.
b)- Evitare ancora di ripetere ad ogni avvio la produzione automatica di una copia di salvataggio del relativo Database se fra la prima e la seconda volta non è passato almeno un giorno.
la protezione a) dovrebbe essere generata dall'uso del comando
a.1) se il programma NON è attivo : non restituisce niente
a.2) se il programma è attivo, restituisce : $ pidof DomusRatio.Lazarus
4591
la protezione b) dovrebbe essere di non difficile soluzione, sfruttando opportunamente il comando
debugfs -R 'stat <inode_number>' /dev/sdb1
relativo al file da interrogare.
Ora, se non avete altre indicazioni, non mi resta che modificare il programma per comprendervi i comandi suddetti
Ciao, per quanto riguarda il quesito a) potresti usare questo: https://wiki.freepascal.org/UniqueInstance io non l'ho mai fatto, perché ho scoperto tardi che esisteva, ed uso un metodo simile a quello che hai scritto tu.
Per quanto riguarda invece il quesito b), puoi fare tutto da Lazarus, senza scomodare il sistema operativo:
const CstConvDataErr=-1;
function DataUltimaModifica(const NomeFile:String):TDateTime;
var DataFile:Longint;
begin
DataFile:=FileAgeUTF8(NomeFile);
//In caso di file non trovato, DataFile vale -1
if (DataFile = -1) then begin
Result:=CstConvDataErr;
end else begin
UnixToDateTime(UnixFileTime);
end;
end;
Devi aggiungere alla uses "dateutils e LazFileUtils". La funzione riceve in input il nome del file, e restituisce la data di ultima modifica di tale file.
Usando poi l'istruzione DaysBetween, puoi verificare quanti giorni di difeerenza ci sono tra oggi e tale data
Ciao, Mario
Mi spiace, ma non ti so aiutare, se mastichi l'inglese, potresti chiedere sul forum internazionale.
. . .
P.S. Anche la soluzione che avevi trovato tu va bene, se per te è più semplice quella, usa quella. Magari fai una funzione apposta da richiamare quando ti serve, così se un domani volessi cambiarne il funzionamento, ti basterà modificare il contenuto di tale funzione e, tutti i programmi che la chiamano andranno solo ricompilati.
Si, riprendere la mia idea potrebbe essere una soluzione. Dovrei però superare due ostacoli:
- fare partire il controllo prima che compaia la Form1 a video;
- Individuare e superare l'errore di eccezione che ricevo all'avvio del programma:
Il progetto DomusRatio ha sollevato una eccezione di classe 'EProcess' con messaggio:
Executable not found: "pidof DomusRatio.Lazarus > /media/dirdati/dativari/lazarus_progetti/lazarus_progetti_miei/DomusRatio/bin/file_pidof".
All'indirizzo 714BD4
L'errore si manifesta all'esecuzione dell'istruzione evidenziata nel gruppo Aprocess seguente:
procedure TForm1.FormCreate(Sender: TObject);
const
meno: Char = '-';
var
AProcess: Tprocess;
striMia: String;
begin
percorso := ExtractfilePath(Application.ExeName);
striMia:= 'pidof DomusRatio.Lazarus ' + Chr(62) + ' ' + percorso + 'file_pidof';
AProcess := Tprocess.Create(nil); // costruttore (Crea una nuova istanza della classe TProcess)
AProcess.Executable:= striMia;
AProcess.Options := AProcess.Options + [poWaitOnExit]; // l’opzione [poWaitOnExit] fa si che il programma corrente riprenda il suo percorso soltanto dopo che il comando pidof sarà terminato
Aprocess.Execute; <<---------- ERRORE ERRORE ERRORE
Aprocess.Free; // conclude logicamente il processo appena terminato, liberando l’area di memoria impegnata durante l’esecuzione
ShowMessage('leggi "file_pidof"');
Vi ringrazio per i vostri suggerimenti.
Tuttavia, visto che ho difficolta' con gli strumenti Lazarus e visto che non riesco a fare funzionare nel mio programma il comando pidof, ho optato per una terza soluzione, inserendo l'avvio del programma DomusRatio in uno script che ho scritto oggi.
Allo stesso script ho affidato l'uso del comando pidof reindirizzandone l'output su un file che interrogo subito dopo per sapere se l'applicativo è già attivo. Funziona benissimo e mi posso accontentare così.
Riporto,, per completezza, lo script che ho preparato e provato:
#!/bin/bash
# Script 'domusratio.sh' di:
# avvio del programma di CONTABILITA' FAMILIARE
# ---------------------------------------------------
# scritto il 11-luglio-2022
#-------
clear
echo "Sono le ore $(date +%k)":"$(date +%M)"
echo "----------------------------"
#---variabili
destin="/media/dirdati/dativari/lazarus_progetti/lazarus_progetti_miei/DomusRatio/bin/file_pidof"
let n=0
record=
#---
pidof DomusRatio.Lazarus > $destin
while read record
do
((n += 1))
done < $destin
# echo "record letti= $n"
{
if [ $n = 0 ]
then
"/media/dirdati/dativari/lazarus_progetti/lazarus_progetti_miei/DomusRatio/bin/DomusRatio.Lazarus"
fi
}
exit 0
Purtroppo ho l'obbligo di avviarlo da terminale shell, ma sono sicuro di avviar il programma soltanto dopo avere accertato che non è attivo.
Ora mi resta soltanto di evitare la produzione di una copia del DB automatica all'avvio del programma, entro un certo intervallo di tempo dalla precedente.
Ora mi resta soltanto di evitare la produzione di una copia del DB automatica all'avvio del programma, entro un certo intervallo di tempo dalla precedente.
per questo puoi partire da qua
for myfile in *.iso; do echo echo $myfile = $((($(date +%s) - $(date +%s -r "$myfile")) / 86400)) days; done