erneuten Programmstart verhindern

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Vbxler
Beiträge: 129
Registriert: Sa 25. Mai 2013, 07:43
OS, Lazarus, FPC: Win7_x64 (FPC:4.7.1)
CPU-Target: 32Bit

erneuten Programmstart verhindern

Beitrag von Vbxler »

Hallo zusammen,

mit einem Programm werden Messwerte unter Win11 aus einer Steuerung gelesen und abgelegt.
Das funktioniert auch alles bestens. Leider ist es schon vorgekommen, dass das Programm
von einem Bediener versehentlich geschlossen wurde. Jetzt will ich den Programmstart in den
Aufgabenplanung von Windows alle 10 Minuten durchführen und wenn das Programm
schon läuft, dann wird der neue Prozess wieder sofort beendet.

Das habe ich so machen:
[code]
program Prog_Main;
{$mode objfpc}{$H+}

uses
Interfaces, Forms, uProg_Main, SysUtils, UniqueInstanceRaw;
{$R *.res}

begin
//Abfragen ob die Anwendung bereits gestartet
if InstanceRunning then
Beep;
Application.Terminate
else
begin
RequireDerivedFormResource := True;
Application.Scaled :=True;
Application.Initialize;
Application.CreateForm(TfrmProg_Main, frmDaten);
Application.Run;
end;
end.[/code]

Wenn ich das Progemm über den Explorer startet öffnet sich die Anwendung und verrichtet
die Aufgaben ohne Probleme. Wenn ich im Explorer das Programm erneut starte kommt ein Beep-Ton
und der Process wird wieder beendet. Mit der Enter-Taste kann ich das Programm x-Mal wieder starten,
im Taskmanager erscheint kein neuer Prozess, nur der Task vom ersten Programmstart.

Jetzt hat der Kunde die neue Programmversion rein kopiert und am Ende
des Tages waren aber mehrere Prozesse des Programms am laufen.

Frage:
Ist die Abfrage der Instance hier die ehest mögliche, bzw. wie könnte ich das besser lösen?

Danke für eure Hilfe!

sstvmaster
Beiträge: 582
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 3.8
CPU-Target: 32+64bit
Wohnort: Dresden

Re: erneuten Programmstart verhindern

Beitrag von sstvmaster »

Hi,

du kannst auch im OnCloseQuery Event eine Abfrage machen, ala "Wollen Sie das Programm wirklich Beenden?".
Danach könntest du noch eine Abfrage machen, "Sind Sie sich wirklich sicher?"

Siehe auch: https://wiki.freepascal.org/user_should ... se_form/de
LG Maik

Windows 10,
- Lazarus 3.8 (stable) + fpc 3.2.2 (stable)
- Lazarus 4.99 (trunk) + fpc 3.3.1 (main/trunk)

Stevie
Beiträge: 162
Registriert: Di 27. Feb 2024, 22:40

Re: erneuten Programmstart verhindern

Beitrag von Stevie »

... ich hoffe, das ist nur Pseudo Code, denn das würde nicht compilieren und wenn, dann würde es nicht den gewünschten Effekt haben, da Dein Programm bei jedem Start sofort wieder beendet werden würde...

Code: Alles auswählen

...
begin
  //Abfragen ob die Anwendung bereits gestartet
  if InstanceRunning then
    Beep;
  Application.Terminate
  else
    begin
      RequireDerivedFormResource := True;
      Application.Scaled :=True;
      Application.Initialize;
      Application.CreateForm(TfrmProg_Main, frmDaten);
      Application.Run;
    end;
end.
... und wahrscheinlich ist "InstanceRunning" der wohl einfachste Weg.

schoschy
Beiträge: 56
Registriert: Di 18. Okt 2022, 15:46

Re: erneuten Programmstart verhindern

Beitrag von schoschy »

Ich verwende
https://wiki.lazarus.freepascal.org/UniqueInstance
Da kannst du dir aussuchen, ob das bestehende oder neue Programm wieder geschlossen werden soll.

Das schließen unterbinden ist natürlich die schönere Lösung.

Vbxler
Beiträge: 129
Registriert: Sa 25. Mai 2013, 07:43
OS, Lazarus, FPC: Win7_x64 (FPC:4.7.1)
CPU-Target: 32Bit

Re: erneuten Programmstart verhindern

Beitrag von Vbxler »

Hallo schoschy,

danke für den Hinweis!
Habe jetzt gesehen, dass die von mir verwendeten uniqueinstance Datein
aus 2007 stammen. Darin wird vermutlich das Problem iegen.
Ich werde mir gleich die aktuellen Dateien aus 2017 besorgen und es damit versuchen.

Vielern Dank

Singlepin
Beiträge: 15
Registriert: Fr 28. Aug 2015, 17:00
OS, Lazarus, FPC: Ubuntu 24.04.1 LTS (L 3.6 FPC 3.2.2)
CPU-Target: 64Bit

Re: erneuten Programmstart verhindern

Beitrag von Singlepin »

Unter Windows hatte ich das immer so gemacht.

Code: Alles auswählen

uses Windows

  function AllowSetForegroundWindow(AHandle: HWND): Boolean; external 'user32.dll';

var
  hFMapping:THandle;
  FSpeicher:^THandle;
  FHandle:THandle;
const appName='NAME';

implementation

procedure TForm1.FormShow(Sender: TObject);
begin
FSpeicher:=MapViewOfFile(hFMapping,FILE_MAP_WRITE,0,0,0);
FSpeicher^:=Application.MainForm.Handle;
UnmapViewOfFile(FSpeicher);
end;

Initialization

hFMapping:=CreateFileMapping(INVALID_HANDLE_VALUE,NIL,PAGE_READWRITE,
                            0,sizeof(Application.MainForm.Handle),appName);
if hFMapping<>0
 then
  begin
  if GetLastError=ERROR_ALREADY_EXISTS
   then
    begin
    FSpeicher:=MapViewOfFile(hFMapping,FILE_MAP_READ,0,0,0);
//    FSpeicher^:=Application.MainForm.Handle;
    FHandle:=FSpeicher^;
    UnmapViewOfFile(FSpeicher);
    AllowSetForegroundWindow(FHandle);
    ShowWindow(FHandle,SW_Normal); // Fenster auf Normal
    SetForegroundWindow(FHandle);  // in den Vordergrund bringen
    halt;
    end
  end
 else
  begin
  Application.MessageBox('Fehler beim Erstellen des Mapping','Abbruch',MB_OK);
  Halt;
  end;

finalization

if hFMapping<>0 then CloseHandle(hFMapping)

Rheinländer
Beiträge: 6
Registriert: Di 1. Okt 2024, 13:05

Re: erneuten Programmstart verhindern

Beitrag von Rheinländer »

Hallo,
für die Anforderung wird unter Windows die Mutex Routinen vom Betriebsystem genommen. Wie es benutzt wird ist hier erklärt.

Vbxler
Beiträge: 129
Registriert: Sa 25. Mai 2013, 07:43
OS, Lazarus, FPC: Win7_x64 (FPC:4.7.1)
CPU-Target: 32Bit

Re: erneuten Programmstart verhindern

Beitrag von Vbxler »

Danke Rheinländer,

das werde ich mal testen.

Antworten