zweite Programm-Start verhindern (FileLock)

Veröffentlicht von

Hier mal eine kleine Funktion, wie man einen zweiten Programm-Start verhindert, wenn das Programm schon Läuft.

Dazu verwende ich eine Datei, die ich mit der „FileLock-Klasse“ sperre und versuche die Datei zu löschen, wenn ich das Programm starte.

Als erstes die Variablen

private static String lockFileOrdnerName = "lockfiles";
private static String lockFileName = "startLock.ini";
private static FileLock lockedFile;

Hier den Code in der Main-Methode einbinden

	public static void main(String[] args) {
        if (isLocked(getPfadLockDatei())) {
            System.out.println("Starten");   
            lockedFile = setLock(getPfadLockDatei());
            launch(args);           
        } else {
            System.out.println("Läuft schon");
            meldung(AlertType.WARNING, "", "Das Programm läuft schon");
        }		
	}

Dann noch den Code einbinden, wenn das Fenster wieder geschlossen wird, die Datei frei geben.

	@Override
	public void stop() throws Exception {
		System.out.println("Stop");
		releaseLock(lockedFile);
	}

 

Die dazugehörigen Methoden.

	private static File getProgrammPfad() {
		PfadErmitteln pe = new PfadErmitteln(new String[]{}, false , false );
		File programmPfad = pe.getErmittelterFile();
		return programmPfad;
	}
	
	private static  File getPfadLockOrdner() {
		File lockOrdnerPfad = new File(getProgrammPfad() + File.separator + lockFileOrdnerName);
		return lockOrdnerPfad;		
	}
	
	private static  File getPfadLockDatei() {
		File lockDateiPfad = new File(getPfadLockOrdner() + File.separator + lockFileName);
		return lockDateiPfad;
	}
	
	private static boolean isLocked(File file) {		
			
		if (file.exists()) {
			System.out.println("Datei vorhanden");	
			// Test ob die LockDatei gelöscht werden kann 
			// - wenn die LockDatei nicht gelöscht werden kann, dann läuft das Programm schon
			// - wenn die LockDatei gelöscht werden kann, dann läuft das Programm noch nicht
			if (!file.delete()) {
				System.out.println("Datei gesperrt");
		        return false;
		    } else {
		    	System.out.println("Datei frei");
		    	return true;
		    }		
			
		} else {
			// LockOrdner und LockDatei erstellen, wenn noch nicht vorhanden
			if (createLockFileOrdner(getPfadLockOrdner())) {
				try {
					if (file.createNewFile()) {
						isLocked(file);
					} else {
						meldung(AlertType.WARNING, "", "Die Lock-Datei konnte nicht erstellt werden.");
					}
				} catch (IOException e) {
					meldung(AlertType.ERROR, "", "Fehler beim erstellen der Lock-Datei.");
					e.printStackTrace();
				}
			}

			return true;
		}	
	}

	private static boolean createLockFileOrdner(File lockOrdnerPfad) {

			// Ordner erstellen, wenn es ihn noch nicht gibt
			if (!lockOrdnerPfad.exists()) {
			    System.out.println("creating directory: " + lockOrdnerPfad.getName());
			    boolean result = false;
			
			    try{			    	
			    	if (lockOrdnerPfad.mkdir()) {
			    		System.out.println("LockFileOrdner \"" + lockOrdnerPfad + "\" erstellt");  
						return true;
					}			    	
			    } 
			    catch(SecurityException se){
			        se.printStackTrace();
			    }        
			} else {
				System.out.println("LockFileOrdner \"" + lockOrdnerPfad + "\" gibt es schon");
				return true;
			}
			
			return false;
	}
	
	private static FileLock setLock(File file) {
		// LockFile locken
        try {
            return new RandomAccessFile(file, "rw").getChannel().tryLock();
        } catch (IOException ex) {
            System.out.println("Fehler " + ex.toString());
            return null;
        }

	}

	  private static void releaseLock(FileLock lock) {
		  	// LockFile wieder frei geben
	        if (lock != null) {
	            try {
	                lock.release();
	                System.out.println("Datei-Lock release " + lock.toString());
	                new Thread(task).start();
	            } catch (IOException ex) {
	                System.out.println("Cant release lock on " + lock.toString());
	                meldung(AlertType.WARNING, "", "\"lock.release()\" konnte nicht ausgefürt werden.");
	            }
	        }
	    }
	
	  private static void meldung(AlertType alertType, String title, String ContentText) {
		  Platform.runLater(new Runnable() {
				@Override
				public void run() {
					Alert alert = new Alert(alertType);
					alert.setTitle(title);
					alert.setHeaderText(null);
					alert.setContentText("Das Programm läuft schon");
	
					alert.showAndWait();					
				}
		  });
	  } 
	  
		// Alert muss in einem Task ausgeführt werden, sonst gibt es eine Exception
		static Task task = new Task<Void>() {
		    @Override public Void call() {
	      	    	if (!getPfadLockDatei().delete()) {
	    				meldung(AlertType.WARNING, "", "Lock-Datei konnte nicht gelöscht werden.");
	    		    } else {
	    		    	System.out.println("Lock-Datei wurde gelöscht");
					}
				return null;
		    }
		};

 

Und zum Schluss nochmal ein Beispiel mit einem Fenster.

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.*;
import java.nio.channels.FileLock;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

import application.funktionen.PfadErmitteln;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class DateiLock extends Application {

	private static String lockFileOrdnerName = "lockfiles";
	private static String lockFileName = "startLock.ini";
	private static FileLock lockedFile;
	
	private Button button;
	
	@Override
	public void start(Stage primaryStage) {
		try {
			primaryStage.setTitle("Fenster");

			StackPane root = new StackPane();
			Scene scene = new Scene(root,400,400);

			button = new Button();
			button.setText("Klick mich");

			root.getChildren().add(button);

			primaryStage.setScene(scene);
			primaryStage.show();
			
		} catch(Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void stop() throws Exception {
		System.out.println("Stop");
		releaseLock(lockedFile);
	}
	
	public static void main(String[] args) {
        if (isLocked(getPfadLockDatei())) {
            System.out.println("Starten");   
            lockedFile = setLock(getPfadLockDatei());
            launch(args);           
        } else {
            System.out.println("Läuft schon");
            meldung(AlertType.WARNING, "", "Das Programm läuft schon");
        }		
	}
	
	private static File getProgrammPfad() {
		PfadErmitteln pe = new PfadErmitteln(new String[]{}, false , false );
		File programmPfad = pe.getErmittelterFile();
		return programmPfad;
	}
	
	private static  File getPfadLockOrdner() {
		File lockOrdnerPfad = new File(getProgrammPfad() + File.separator + lockFileOrdnerName);
		return lockOrdnerPfad;		
	}
	
	private static  File getPfadLockDatei() {
		File lockDateiPfad = new File(getPfadLockOrdner() + File.separator + lockFileName);
		return lockDateiPfad;
	}
	
	private static boolean isLocked(File file) {		
			
		if (file.exists()) {
			System.out.println("Datei vorhanden");	
			// Test ob die LockDatei gelöscht werden kann 
			// - wenn die LockDatei nicht gelöscht werden kann, dann läuft das Programm schon
			// - wenn die LockDatei gelöscht werden kann, dann läuft das Programm noch nicht
			if (!file.delete()) {
				System.out.println("Datei gesperrt");
		        return false;
		    } else {
		    	System.out.println("Datei frei");
		    	return true;
		    }		
			
		} else {
			// LockOrdner und LockDatei erstellen, wenn noch nicht vorhanden
			if (createLockFileOrdner(getPfadLockOrdner())) {
				try {
					if (file.createNewFile()) {
						isLocked(file);
					} else {
						meldung(AlertType.WARNING, "", "Die Lock-Datei konnte nicht erstellt werden.");
					}
				} catch (IOException e) {
					meldung(AlertType.ERROR, "", "Fehler beim erstellen der Lock-Datei.");
					e.printStackTrace();
				}
			}

			return true;
		}	
	}

	private static boolean createLockFileOrdner(File lockOrdnerPfad) {

			// Ordner erstellen, wenn es ihn noch nicht gibt
			if (!lockOrdnerPfad.exists()) {
			    System.out.println("creating directory: " + lockOrdnerPfad.getName());
			    boolean result = false;
			
			    try{			    	
			    	if (lockOrdnerPfad.mkdir()) {
			    		System.out.println("LockFileOrdner \"" + lockOrdnerPfad + "\" erstellt");  
						return true;
					}			    	
			    } 
			    catch(SecurityException se){
			        se.printStackTrace();
			    }        
			} else {
				System.out.println("LockFileOrdner \"" + lockOrdnerPfad + "\" gibt es schon");
				return true;
			}
			
			return false;
	}
	
	private static FileLock setLock(File file) {
		// LockFile locken
        try {
            return new RandomAccessFile(file, "rw").getChannel().tryLock();
        } catch (IOException ex) {
            System.out.println("Fehler " + ex.toString());
            return null;
        }

	}

	  private static void releaseLock(FileLock lock) {
		  	// LockFile wieder frei geben
	        if (lock != null) {
	            try {
	                lock.release();
	                System.out.println("Datei-Lock release " + lock.toString());
	                new Thread(task).start();
	            } catch (IOException ex) {
	                System.out.println("Cant release lock on " + lock.toString());
	                meldung(AlertType.WARNING, "", "\"lock.release()\" konnte nicht ausgefürt werden.");
	            }
	        }
	    }
	
	  private static void meldung(AlertType alertType, String title, String ContentText) {
		  Platform.runLater(new Runnable() {
				@Override
				public void run() {
					Alert alert = new Alert(alertType);
					alert.setTitle(title);
					alert.setHeaderText(null);
					alert.setContentText("Das Programm läuft schon");
	
					alert.showAndWait();					
				}
		  });
	  } 
	  
		// Alert muss in einem Task ausgeführt werden, sonst gibt es eine Exception
		static Task task = new Task<Void>() {
		    @Override public Void call() {
	      	    	if (!getPfadLockDatei().delete()) {
	    				meldung(AlertType.WARNING, "", "Lock-Datei konnte nicht gelöscht werden.");
	    		    } else {
	    		    	System.out.println("Lock-Datei wurde gelöscht");
					}
				return null;
		    }
		};
}