Mehrere Instanzen eines Programms verhindern

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

 

MindWorm

Betreff: Mehrere Instanzen eines Programms verhindern

BeitragMi, Okt 15, 2008 21:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Guten Abend,

Ich hab die Tage ein kleines Notizen- und ToDo-Programm mit BlitzMax und MaxGUI geschrieben und frage mich nun, ob es möglich ist, nur eine einzige Instanz des Programms laufen zu haben und das Starten einer weiteren Instanz zu erkennen und zu verhindern.

Ich stelle mir das so vor: Ich habe eine Verknüpfung zu meinem Programm in der Schnellstartleiste, wenn ich diese betätige, dann öffnet sich ganz normal das Programm. Wenn ich diese Verknüpfung dann ein weiteres Mal öffne, soll sich nun nicht eine zweite Instanz des Programms öffnen, sondern stattdessen soll sich die erste Instanz wieder schließen.

Ist das mit BlitzMax irgendwie realisierbar? Falls ja, wäre es nett, wenn mich jemand in die richtige Richtung stoßen würde Smile
Optimal wäre eine vom Betriebsystem unabhängige Lösung, für's erste würde aber auch eine Lösung für Windows genügen.
 

jsp

BeitragMi, Okt 15, 2008 22:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Den Code einfach compilieren und dann versuchen zweimal zu starten.
Leider nur Windows...

Code: [AUSKLAPPEN]

SuperStrict
Import MaxGui.Drivers

Global Mutex:Int

OnEnd ReleaseInstance
If InitSingleInstance("Prog1") Then DebugLog "ok" Else Notify "Prog1 laeuft schon!";End


Local Window1:TGadget = CreateWindow:TGadget("Window1",357,138,236,143,Null,WINDOW_TITLEBAR|WINDOW_RESIZABLE |WINDOW_STATUS |WINDOW_CLIENTCOORDS )
   Local Ende:TGadget = CreateButton:TGadget("End",75,48,75,23,Window1:TGadget,BUTTON_PUSH)

Repeat
   WaitEvent()
   Select EventID()
      Case EVENT_WINDOWCLOSE
         Select EventSource()
            Case Window1   Window1_WC( Window1:TGadget )
         End Select

      Case EVENT_GADGETACTION
         Select EventSource()
            Case Ende   Ende_GA( Ende:TGadget )
         End Select

   End Select
Forever

Function Window1_WC( Window:TGadget )
   DebugLog "Window Window1 wants to be closed"
'   HideGadget( Window:TGadget )

   End
End Function

Function Ende_GA( Button:TGadget )
   DebugLog "Button End was pressed"
   End
End Function

Function InitSingleInstance:Int( name:String)
   DebugLog "Create singele instance"
?Win32
   Extern "Win32"
      Const ERROR_ALREADY_EXISTS:Int = 183
      
      Function CreateMutexW:Int( security:Byte Ptr, owner:Int, name$w)
      Function GetLastError:Int()
   EndExtern
   
   Mutex = CreateMutexW( Null, True, name)
   If (Not Mutex) Or (GetLastError() = ERROR_ALREADY_EXISTS) Then Return False
?
   Return True
EndFunction

Function ReleaseInstance()
   DebugLog "Release Mutex"
   Extern "Win32"
      Function ReleaseMutex:Int( mutex:Int)
   EndExtern
   
   If Mutex Then
      ReleaseMutex( Mutex)
      Mutex = 0
   EndIf
EndFunction


-jsp-
Logic Gui Professional a Gui Designer for MaxGui

hamZta

Administrator

BeitragMi, Okt 15, 2008 22:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Um das ganze plattformunabhängig zu machen (und somit einen der größten Vorteile BlitzMax wiederzugewinnen Wink ) könntest du, wenn das Programm gestartet wird eine Datei anlegen bzw. bevor du das machst prüfen, ob diese Datei existiert und dann eben die entsprechenden Schritte einleiten.

mfg,
hamZta
Blog.
 

jsp

BeitragMi, Okt 15, 2008 23:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Hmm, das koennte zu Probleme fuehren wenn dein Programm einmal abstuerzt und die Datei nicht mehr loeschen kann. Beim naechsten Programmstart wird die Datei gefunden und nichts gehr mehr.
Fuer einen selbst ist das ja kein Problem, aber wenn man die Software weitergibt...
Logic Gui Professional a Gui Designer for MaxGui

Valnar

BeitragDo, Okt 16, 2008 1:33
Antworten mit Zitat
Benutzer-Profile anzeigen
hamZta hat Folgendes geschrieben:
Um das ganze plattformunabhängig zu machen (und somit einen der größten Vorteile BlitzMax wiederzugewinnen Wink ) könntest du, wenn das Programm gestartet wird eine Datei anlegen bzw. bevor du das machst prüfen, ob diese Datei existiert und dann eben die entsprechenden Schritte einleiten.

mfg,
hamZta
So machen es auch viele Linux-Programme wie Apache und co.
Wenn das Programm abstürzt einfach Datei Löschen -> Fertig.

Notfalls kannst du in die Datei auch jede Minuten die Aktuelle Zeit reinschrieben und bei Start einer neuen Instanz prüfen ob die Zeit Älter ist als es sein dürfte...

Geeecko

BeitragDo, Okt 16, 2008 15:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Man könnte auch einfach einen TCP-Server erstellen auf Port bla.
Das Programm prüft, ob es einen Server auf port bla erstellen kann. wenn nicht, dann läuft das prog. noch.
Der Stream wird auf alle fälle geschlossen.

lg MD
 

MindWorm

BeitragDo, Okt 16, 2008 18:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke für Eure Vorschläge!

Ich werde erstmal das mit der Datei ausprobieren, da ich so die plattformunabhängigkeit wahren kann. Das mit dem TCP-Server hört sich aber auch gut an. Hm, ich probiere einfach mal ein bischen rum Wink

Geeecko

BeitragSa, Okt 18, 2008 13:02
Antworten mit Zitat
Benutzer-Profile anzeigen
http://msdn.microsoft.com/de-d...78969.aspx
Hab noch was gefunden.

lg MD

BladeRunner

Moderator

BeitragSa, Okt 18, 2008 13:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Ich werde erstmal das mit der Datei ausprobieren, da ich so die plattformunabhängigkeit wahren kann.

Da ist die MSDN (sprich WIN-Api) natürlich genau das richtige für, Meisterdieb. Entspricht ganz seinen Bedürfnissen.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

Geeecko

BeitragSa, Okt 18, 2008 15:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Bist ja ganz meiner Meinung!
Finde ich auch
Vorallem weil es ja nicht "?win" gibt.
Wäre auch zu schön wenns das geben würde

BladeRunner

Moderator

BeitragSa, Okt 18, 2008 17:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Ist ja auch sehr sinnig wenn das Programm auf einer Plattform wie gewünscht (öffnen beim ersten Aufruf, schliessen bein zweiten) funktioniert und auf den beiden anderen nicht.
Da ist er mit der Textdatei mit Zeitstempel wesentlich besser beraten. TCP ist insofern sinnfrei als dass wenn sich irgendein anderes Programm schon über den Port eine Verbindung aufbauen sollte dieses hier niemals starten würde, und warum mit der WinAPI rumpfuschen wenn es eine einfache und effiziente Lösung ohne sie gibt.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92
 

jsp

BeitragSa, Okt 18, 2008 20:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn es denn schon eine Lock Datei sein soll (ist nicht wirklich mit einem Mutex vergleichbar, wenn es zu Multi User, Multi Thread, Multi Desktop kommt – auch gerade unter Unix ) wäre vielleicht folgender Weg besser als ein Zeitstempel:

Erstes Programm startet und legt eine Datei an.
Wenn die Datei vorhanden ist wird sie zum Schreiben (!) geöffnet.

Zweites Programm startet und findet die Datei, ok, „erstes“ Programm könnte vielleicht abgestürzt sein und konnte die Datei nicht löschen – wissen wir nicht.
Kann die Datei zum Schreiben geöffnet werden, dann ist die Datei nicht gelockt und die Datei ist nur ein Überbleibsel. Gibt es eine Fehlermeldung dann läuft „erstes“ Programm noch und „zweites“ Programm kann sich wieder schließen.

Nach einem Absturz, Hänger oder neu booten, ist jeweils der Filelock vom OS (ausgelöst durch das zum Schreiben öffnen) aufgehoben und man kann sein Programm normal starten.

Man sollte natürlich seine Lock Datei löschen, wenn man das Programm normal beendet, auch wenn es nicht zwingend erforderlich wäre. Obwohl so eine Lock Datei ganz nett ist, wäre eine OS gestützte Variante vorzuziehen, von daher sehe ich die WinApi Möglichkeit nicht so verbissen, es gibt viele Dinge die mit einer Datei schief gehen können.

-jsp-
Logic Gui Professional a Gui Designer for MaxGui

BtbN

BeitragSa, Okt 18, 2008 20:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Problem nur: Linux kennt keine solchen locks. Hast du passende Rechte, kannst du jederzeit eine Datei lesen, schreiben, löschen.
 

jsp

BeitragSa, Okt 18, 2008 22:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Kenne mich persönlich besser mit AIX als mit Linux aus, aber ich hab mal kurz nachgeschaut und Linux scheint auch mandatory locking zu unterstützen. Ist vielleicht besser als nichts:
http://www.hackinglinuxexposed...30623.html
Logic Gui Professional a Gui Designer for MaxGui

Blitzcoder

Newsposter

BeitragSa, Okt 18, 2008 22:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
To enable mandatory locking, you must first mount the filesystem with the mand mount option:


Ich bezweifle dass diese Option standardmäßig von mount gesertzt wird.
P4 3 Ghz@3,55Ghz|GF 6600GT 256MB|Samsung 80GB | 2x Samsung 160GB|2048MB DDR-400 RAM|6 Mbit Flatrate | Logitech G15 | Samsung 225BW-TFT | Ubuntu Gutsy Linux | Windows Vista | Desktop | Blog | CollIDE | Worklog
________________
|°°°°°°°°°°°°°°||'""|""\__,_
|______________ ||__ |__|__ |)
|(@) |(@)"""**|(@)(@)****|(@)
 

jsp

BeitragSo, Okt 19, 2008 1:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Gut moeglich, aber dann koennte man das ja mal auf Dateiebene ausprobieren:

chmod g+s,g-x Datei

Wer ja mal ein Versuch wert.
Logic Gui Professional a Gui Designer for MaxGui

BtbN

BeitragSo, Okt 19, 2008 10:01
Antworten mit Zitat
Benutzer-Profile anzeigen
jsp hat Folgendes geschrieben:
chmod g+s,g-x Datei


Verhindert nicht, dass ich die Datei unbedarft löschen kann.

Geeecko

BeitragSo, Okt 19, 2008 10:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Bisher finde ich das mit dem TCP am besten. Es funktioniert auf jedem System.
Und das mit dem Port ist auf keinen Fall das Problem, BR.

BtbN

BeitragSo, Okt 19, 2008 10:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Man Könnte das eventuell kombinieren mit TCP und Datei. Das erste programm schreibt in eine Datei, auf welchem zufälligen Port es horcht, und das zweite gestartete guckt in die Datei, und schaut ob es auch auf dem Port binden kann. Wenn ja, ist die erste instanz abgestürzt, wenn nein, läuft die erste instanz noch, wenns die Datei nicht gibt, wurde noch keine erste instanz gestartet.
 

jsp

BeitragSo, Okt 19, 2008 11:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Verhindert nicht, dass ich die Datei unbedarft löschen kann.


Unbedarft löschen kann man ja immer, da ist als root user nichts sicher, aber das sollte bei so einer Lock-Datei eigentlich kein Problem sein, wird im Normalfall ja nur vom Programm drauf zugegriffen.

Zitat:
Man Könnte das eventuell kombinieren mit TCP und Datei.


Die Idee finde ich eigentlich gar nicht schlecht. Man muss sich nicht einen festen Port greifen, was unter Umständen zu Problemen führen könnte und man kann am Port testen ob die andere Instanz noch lebt. Es war mal weit verbreitet bei Firmen, das sie die Programm Seriennummer so aufs LAN verbreitet haben. Dadurch hat man versucht, das keine Kopie mit gleicher Nummer gestartet werden konnte, aber war halt nicht wirklich sicher und zumindest in meinem Arbeitsbereich ist jetzt alles nur noch mit Dongle zu betreiben. Vielleicht kann man nicht nur testen ob der Port „lebt“ sondern tatsächlich prüfen, z.B. wie viele Instanzen erlaubt sind, falls das wichtig ist.
Logic Gui Professional a Gui Designer for MaxGui

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group