Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Verhindern, dass Programm zweimal läuft...
Gehe zu Seite 1, 2  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
csde_rats



Anmeldungsdatum: 07.01.2007
Beiträge: 2292
Wohnort: Zwischen Sessel und Tastatur

BeitragVerfasst am: 15.09.2007, 17:02    Titel: Verhindern, dass Programm zweimal läuft... Antworten mit Zitat

Hallo!
Wie kann ich verhindern, dass man unter Windows 2xdas eigene Programm ausführt? (Also, dass nur eine Instanz gleichzeitig laufen kann)
_________________
If hilfreicher_Beitrag then klick(location.here)

Klick
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 15.09.2007, 17:04    Titel: Antworten mit Zitat

eine relativ gesehen unpräzise auskunft...

Code:

' zunächst die benötigten API-Deklarationen
Private Declare Function CreateToolhelpSnapshot Lib _
  "Kernel32" Alias "CreateToolhelp32Snapshot" ( _
  ByVal lFlgas As Long, ByVal lProcessID As Long) _
  As Long
 
Private Declare Function ProcessFirst Lib "Kernel32" _
  Alias "Process32First" (ByVal hSnapshot As Long, _
  uProcess As PROCESSENTRY32) As Long
 
Private Declare Function ProcessNext Lib "Kernel32" _
  Alias "Process32Next" (ByVal hSnapshot As Long, _
  uProcess As PROCESSENTRY32) As Long
 
Private Declare Sub CloseHandle Lib "Kernel32" ( _
  ByVal hPass As Long)

Private Const TH32CS_SNAPPROCESS As Long = 2&
Private Const MAX_PATH As Long = 260
 
Private Type PROCESSENTRY32
  dwSize As Long
  cntUsage As Long
  th32ProcessID As Long
  th32DefaultHeapID As Long
  th32ModuleID As Long
  cntThreads As Long
  th32ParentProcessID As Long
  pcPriClassBase As Long
  dwflags As Long
  szexeFile As String * MAX_PATH
End Type

' Prüft, ob eine EXE-Datei bereits ausgeführt wird
Public Function IsEXERunning(ByVal sFilename As String) As Long
 
  Dim lSnapshot As Long
  Dim uProcess As PROCESSENTRY32
  Dim nResult As Long
 
  ' "Snapshot" des aktuellen Prozess ermitteln
  lSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
  If lSnapshot <> 0 Then
    uProcess.dwSize = Len(uProcess)
   
    ' Ersten Prozess ermitteln
    nResult = ProcessFirst(lSnapshot, uProcess)
   
    Do Until nResult = 0
      ' Prozessliste durchlaufen
      If InStr(LCase$(uProcess.szexeFile), LCase$(sFilename)) > 0 Then
        ' Jepp - EXE gefunden
        IsEXERunning = True
        Exit Do
      End If
     
      ' nächster Prozess
      nResult = ProcessNext(lSnapshot, uProcess)
    Loop
   
    ' Handle schliessen
    CloseHandle lSnapshot
  End If
End Function



ist VB, sollte ja leicht übertragbar sein..
wichtig ist, dass du nicht den pfad übergibst, sondern nur den dateinamen, z.B. IsEXERunning("firefox.exe")
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
csde_rats



Anmeldungsdatum: 07.01.2007
Beiträge: 2292
Wohnort: Zwischen Sessel und Tastatur

BeitragVerfasst am: 15.09.2007, 17:17    Titel: Antworten mit Zitat

OK, funktioniert, danke! grinsen
(Die ganzen IfNDef's sind dazu da, evtl. Headerveränderungen abzufangen xD, oder Fehler beim #include "windows.bi" zu verhindern grinsen)
Code:

#Ifndef TH32CS_SNAPPROCESS
   Const TH32CS_SNAPPROCESS As Long = 2&
#EndIf
#Ifndef MAX_PATH
   Const MAX_PATH As Long = 260
#EndIf
#Ifndef PROCESSENTRY32
   Type PROCESSENTRY32
     dwSize As Long
     cntUsage As Long
     th32ProcessID As Long
     th32DefaultHeapID As Long
     th32ModuleID As Long
     cntThreads As Long
     th32ParentProcessID As Long
     pcPriClassBase As Long
     dwflags As Long
     szexeFile As String * MAX_PATH
   End Type
#EndIf
' zunächst die benötigten API-Deklarationen
#Ifndef CreateToolhelpSnapshot
   Declare Function CreateToolhelpSnapshot Lib _
     "Kernel32" Alias "CreateToolhelp32Snapshot" ( _
     ByVal lFlgas As Long, ByVal lProcessID As Long) _
     As Long
#EndIf
#Ifndef ProcessFirst
   Declare Function ProcessFirst Lib "Kernel32" _
     Alias "Process32First" (ByVal hSnapshot As Long, _
     uProcess As PROCESSENTRY32) As Long
#EndIf
#Ifndef ProcessNext
   Declare Function ProcessNext Lib "Kernel32" _
     Alias "Process32Next" (ByVal hSnapshot As Long, _
     uProcess As PROCESSENTRY32) As Long
#EndIf
#Ifndef CloseHandle
   Declare Sub CloseHandle Lib "Kernel32" ( _
     ByVal hPass As Long)
#EndIf

' Prüft, ob eine EXE-Datei bereits ausgeführt wird
Function ING_IsEXERunning(ByVal sFilename As String) As Integer
 
  Dim lSnapshot As Long
  Dim uProcess As PROCESSENTRY32
  Dim nResult As Long
 
  ' "Snapshot" des aktuellen Prozess ermitteln
  lSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
  If lSnapshot <> 0 Then
    uProcess.dwSize = Len(uProcess)
   
    ' Ersten Prozess ermitteln
    nResult = ProcessFirst(lSnapshot, uProcess)
   
    Do Until nResult = 0
      ' Prozessliste durchlaufen
      If InStr(LCase$(uProcess.szexeFile), LCase$(sFilename)) > 0 Then
        ' Jepp - EXE gefunden
        Return TRUE
        Exit Do
      End If
     
      ' nächster Prozess
      nResult = ProcessNext(lSnapshot, uProcess)
    Loop
   
    ' Handle schliessen
    CloseHandle Cast(Long,lSnapshot)
  End If
End Function

_________________
If hilfreicher_Beitrag then klick(location.here)

Klick
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4699
Wohnort: ~/

BeitragVerfasst am: 15.09.2007, 17:44    Titel: Antworten mit Zitat

Unter Linux legen viele Programme eine lock-Datei an, die nach Programmende wieder gelöscht wird. Wenn diese lock-Datei bereits existiert, dann wird das Programm nicht noch einmal gestartet.
Nachteil ist, dass bei einem unsauberen Beenden die lock-Datei u. U. noch stehen bleibt und von Hand gelöscht werden muss.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
csde_rats



Anmeldungsdatum: 07.01.2007
Beiträge: 2292
Wohnort: Zwischen Sessel und Tastatur

BeitragVerfasst am: 15.09.2007, 20:02    Titel: Antworten mit Zitat

nemored hat Folgendes geschrieben:
Unter Linux legen viele Programme eine lock-Datei an, die nach Programmende wieder gelöscht wird. Wenn diese lock-Datei bereits existiert, dann wird das Programm nicht noch einmal gestartet.
Nachteil ist, dass bei einem unsauberen Beenden die lock-Datei u. U. noch stehen bleibt und von Hand gelöscht werden muss.

Das ist natürlich vieeeel einfacher zu bedienen, und ist sogar noch Platformunabhängig! OK, dann nehme ich das xD
_________________
If hilfreicher_Beitrag then klick(location.here)

Klick
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 15.09.2007, 20:11    Titel: Antworten mit Zitat

Einfacher? Ja, aber du musst benkden, dass du jetzt gezwungenermaßen ein "Safe Mode"-Programm brauchst, das diese Datei löscht, falls dein Programm mal abgestürzt ist...
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Michael712
aka anfänger, programmierer


Anmeldungsdatum: 26.03.2005
Beiträge: 1593

BeitragVerfasst am: 15.09.2007, 22:39    Titel: Antworten mit Zitat

nemored hat Folgendes geschrieben:
Unter Linux legen viele Programme eine lock-Datei an, die nach Programmende wieder gelöscht wird. Wenn diese lock-Datei bereits existiert, dann wird das Programm nicht noch einmal gestartet.
Nachteil ist, dass bei einem unsauberen Beenden die lock-Datei u. U. noch stehen bleibt und von Hand gelöscht werden muss.



Ist das nicht so, dass meistens in einer lock datei die PID gespeichert wird?
Somit wird dann geprüft, ob es einen prozess mit dieser ID gibt, wenn ja, dann wird es nicht 2mal gestartet, wenn nicht, dann schon.

Aber andererseits scheint es nicht immer so zu sein, beispiel von X:

Zitat:
If this server is no longer running, remove /tmp/.X0-lock and start again.

_________________
Code:
#include "signatur.bi"
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
AndT



Anmeldungsdatum: 02.04.2007
Beiträge: 481

BeitragVerfasst am: 16.09.2007, 11:14    Titel: Antworten mit Zitat

Ein Nettes beispiel von mir:
Das lässt sich noch mit der Winapi zusätzlich absichern zwinkern
programmstart.bas:
Code:
' mit -s gui complitieren
open "lock" for input as #1
if lof(1) > 0 then shell "echo Das Programm darf nicht gestartet werden!":close #1:end
open "lock" for output as #1
print #1,1
close #1
shell "programm -run"
kill "lock"

programm.bas:
Code:
dim as integer lockcheck
open "lock" for input as #1
input #1,lockcheck
if lockcheck = 1 and command(1) = "-run" then goto programmstart else Print "Das Programm darf nicht gestartet werden!"
end
programmstart:
screen 14 ' Ganz simpel um STRG+C zu unterbinden :p
print "mit esc beenden"
do
    for i as integer = 1 to 101
        locate 2,1:print " ";i; " "
    sleep 15
    if inkey = chr(27) then exit do
    next
   
    loop
close #1
[/code]
_________________
Bis irgendwann... grinsen


Zuletzt bearbeitet von AndT am 16.09.2007, 11:24, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4699
Wohnort: ~/

BeitragVerfasst am: 16.09.2007, 11:24    Titel: Antworten mit Zitat

Wenn die Lock-Datei Probleme macht: Meine Bankingsoftware z. B. unterbindet einen Zweitstart nicht generell, sondern gibt eine Warnung aus, dass das Programm bereits zu laufen scheint und fragt, ob es trotzdem gestartet werden soll. Wie er das dann regelt, wenn tatsächlich zwei Instanzen laufen (und ob das überhaupt ein Problem darstellt), habe ich nicht ausprobiert.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4699
Wohnort: ~/

BeitragVerfasst am: 16.09.2007, 11:30    Titel: Antworten mit Zitat

@AndT: Dein Code funktioniert auch problemlos ohne GOTO:
Code:
IF lockcheck = 1 AND COMMAND(1) = "-RUN" THEN GOTO programmstart ELSE PRINT "Das Programm darf nicht gestartet werden!"
END
programmstart:

einfach ersetzen durch
Code:
IF lockcheck <> 1 or COMMAND(1) <> "-RUN" THEN
  PRINT "Das Programm darf nicht gestartet werden!"
  'am besten noch ein SLEEP o. ä.
  END
END IF

_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
AndT



Anmeldungsdatum: 02.04.2007
Beiträge: 481

BeitragVerfasst am: 16.09.2007, 12:30    Titel: Antworten mit Zitat

Da war noch eine kleine Sicherheitslücke, mit dem man das Programm trotztem starten konnte..
Ab jetzt unmöglich zwinkern

programmstart.bas:
Code:
' mit -s gui complitieren
OPEN "LOCK" FOR INPUT AS #1
IF LOF(1) > 0 THEN shell "echo Das Programm darf nicht gestartet werden! ":CLOSE #1:END
OPEN "LOCK" FOR OUTPUT AS #1
PRINT #1,1
print #1,int(timer)
CLOSE #1
SHELL "programm -RUN"
KILL "LOCK"

programm.bas:
Code:
DIM AS INTEGER lockcheck,timx
OPEN "LOCK" FOR INPUT AS #1
INPUT #1,lockcheck
input #1,timx

IF int(timx) <> timer and lockcheck = 1 AND COMMAND(1) = "-RUN" THEN GOTO programmstart ELSE PRINT "Das Programm darf nicht gestartet werden!"
END
programmstart:
SCREEN 14 ' Ganz simpel um STRG+C zu unterbinden :p
PRINT "mit esc beenden"
DO
    FOR i AS INTEGER = 1 TO 101
        LOCATE 2,1:PRINT " ";i; " "
    SLEEP 15
    IF INKEY = CHR(27) THEN EXIT DO
    NEXT
   
    LOOP
CLOSE #1

_________________
Bis irgendwann... grinsen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1876
Wohnort: D59192

BeitragVerfasst am: 16.09.2007, 15:16    Titel: Re: Verhindern, dass Programm zweimal läuft... Antworten mit Zitat

csderats hat Folgendes geschrieben:
Hallo!
Wie kann ich verhindern, dass man unter Windows 2xdas eigene Programm ausführt? (Also, dass nur eine Instanz gleichzeitig laufen kann)

Dies funktioniert nur für Programme die mit fbgfx erstellt werden:
Code:
#include once "windows.bi"
Const myProgName = "Previnst" 'Name des Programms
Dim As handle hwnd = FindWindow("fbgfxclass_" & Ucase(myProgName), Null)
If hWnd Then
  MessageBox( hwnd, "Anwendung läuft bereits!", myProgName, MB_ICONERROR )
  SetForegroundWindow(hWnd)'erste Instanz in den Fordergrund
  ShowWindow(hWnd, 1)
  End 'zweite Instanz beenden
End If

'erst nach der Abfrage die fbgfx aktivieren
Screen 18,32

Sleep
End
Achtung: dies konnte ich erstmal nur unter ME testen!
_________________
Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
AndT



Anmeldungsdatum: 02.04.2007
Beiträge: 481

BeitragVerfasst am: 16.09.2007, 19:49    Titel: Antworten mit Zitat

Da fällt mir eine neue (zumindest theoritische) Methode ein..
Das Programm startet IMMER mit einer bestimmten PID z.B. 1110 wenn eine andere PID benutzt wird, verweigert das Programm den Dienst und gibt ein Dialog aus.. z.B dass es nicht gestartet werden kann..
Die Frage ist aber wie man es hinkriegen will, das die PID immer die vorgegebende ist..
_________________
Bis irgendwann... grinsen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Mao



Anmeldungsdatum: 25.09.2005
Beiträge: 4409
Wohnort: /dev/hda1

BeitragVerfasst am: 16.09.2007, 20:36    Titel: Antworten mit Zitat

Das Problem ist leicht gelöst...gar nicht. Zunge rausstrecken
Wäre zudem "etwas" user-unfriendly wenn ein anderes Programm diese PID gerade nutzt.
_________________
Eine handvoll Glück reicht nie für zwei.
--
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
PMedia



Anmeldungsdatum: 14.08.2006
Beiträge: 2847

BeitragVerfasst am: 16.09.2007, 20:46    Titel: Antworten mit Zitat

Man könnte prüfen ob die Fensterklasse existiert, was sich unter Windows als gar nicht mal so schwer erweist grinsen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
dreael
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 2529
Wohnort: Hofen SH (Schweiz)

BeitragVerfasst am: 16.09.2007, 22:13    Titel: Antworten mit Zitat

Zum im Titel genannten Problem: Ziel sollte ja eine in dem Sinn saubere Lösung sein, wo der Lock bei einem harten Prozessstop (Linuxer würden dem "kill -9"-Methode sagen, also hartes Rauswerf-Beenden statt "Graceful termination") nicht mehr als Leiche in der Gegend herumschwirrt.

@AndT: Eine bestimmte PID darfst Du niemals erwarten, diese wird immer dynamisch vergeben! Zu Deiner Theorie: Nur 1-2 KB-Sicherheitspatches oder ein weiteres Programm installiert, womit sich das Startverhalten von Windows ändert, so dass Dein Prozess eine andere PID bekommt.

Am ehesten greift die LOCK-Methode auf eine Datei, nachteilig ist halt nur, dass diese Datei angelegt werden muss. An dieser Stelle würde ich sonst noch eine Chance sehen, etwas Ähnliches mit Semaphoren und Mutexe zu realisieren. Ist unter Linux und jedem UNIX überhaupt kein Problem, bei Windows dagegen weiss ich nicht, wie weit die IPC-Funktionalität auch dort vorhanden ist.
_________________
Teste die PC-Sicherheit mit www.sec-check.net
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
PMedia



Anmeldungsdatum: 14.08.2006
Beiträge: 2847

BeitragVerfasst am: 16.09.2007, 22:57    Titel: Antworten mit Zitat

Man kann auch einen Watchdog einrichten, einen separaten Programmteil, der iwie schaut obs Prog noch lebt, wenn nicht, wiird die Datei gelöscht
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4699
Wohnort: ~/

BeitragVerfasst am: 16.09.2007, 23:51    Titel: Antworten mit Zitat

Das verschiebt das Problem aber nur. Auch der Watchdog kann abgeschossen werden.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
AndT



Anmeldungsdatum: 02.04.2007
Beiträge: 481

BeitragVerfasst am: 17.09.2007, 08:38    Titel: Antworten mit Zitat

oh mann einfacher gehts echt nicht mehr xD
Diesen Code starten
Code:
open "programm.exe" for binary as #1
lock #1,1 to lof(1)
sleep
close #1

und dann mal versuchen programm.exe zu starten, während dieses teil hier läuft xD..
Man erhält nichts weiter als die Fehlermeldung, dass ein Anderes Programm gerade auf diese Datei zugreift.. und dem ist ja auch so xD...
_________________
Bis irgendwann... grinsen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 17.09.2007, 13:05    Titel: Antworten mit Zitat

Davon lässt sich windows nicht sonderlich beeindrucken... mit den Augen rollen
kannst du auch mal deinen tollen ideen vorher testen, bevor du immer groben unfug erzählst?
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Gehe zu Seite 1, 2  Weiter
Seite 1 von 2

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz