Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
csde_rats

Anmeldungsdatum: 07.01.2007 Beiträge: 2292 Wohnort: Zwischen Sessel und Tastatur
|
Verfasst am: 15.09.2007, 17:02 Titel: Verhindern, dass Programm zweimal läuft... |
|
|
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 |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 15.09.2007, 17:04 Titel: |
|
|
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 |
|
 |
csde_rats

Anmeldungsdatum: 07.01.2007 Beiträge: 2292 Wohnort: Zwischen Sessel und Tastatur
|
Verfasst am: 15.09.2007, 17:17 Titel: |
|
|
OK, funktioniert, danke!
(Die ganzen IfNDef's sind dazu da, evtl. Headerveränderungen abzufangen xD, oder Fehler beim #include "windows.bi" zu verhindern )
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 |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4699 Wohnort: ~/
|
Verfasst am: 15.09.2007, 17:44 Titel: |
|
|
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 |
|
 |
csde_rats

Anmeldungsdatum: 07.01.2007 Beiträge: 2292 Wohnort: Zwischen Sessel und Tastatur
|
Verfasst am: 15.09.2007, 20:02 Titel: |
|
|
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 |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 15.09.2007, 20:11 Titel: |
|
|
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 |
|
 |
Michael712 aka anfänger, programmierer
Anmeldungsdatum: 26.03.2005 Beiträge: 1593
|
Verfasst am: 15.09.2007, 22:39 Titel: |
|
|
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 |
|
 |
AndT
Anmeldungsdatum: 02.04.2007 Beiträge: 481
|
Verfasst am: 16.09.2007, 11:14 Titel: |
|
|
Ein Nettes beispiel von mir:
Das lässt sich noch mit der Winapi zusätzlich absichern
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... 
Zuletzt bearbeitet von AndT am 16.09.2007, 11:24, insgesamt einmal bearbeitet |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4699 Wohnort: ~/
|
Verfasst am: 16.09.2007, 11:24 Titel: |
|
|
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 |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4699 Wohnort: ~/
|
Verfasst am: 16.09.2007, 11:30 Titel: |
|
|
@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 |
|
 |
AndT
Anmeldungsdatum: 02.04.2007 Beiträge: 481
|
Verfasst am: 16.09.2007, 12:30 Titel: |
|
|
Da war noch eine kleine Sicherheitslücke, mit dem man das Programm trotztem starten konnte..
Ab jetzt unmöglich
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...  |
|
Nach oben |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 16.09.2007, 15:16 Titel: Re: Verhindern, dass Programm zweimal läuft... |
|
|
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 |
|
 |
AndT
Anmeldungsdatum: 02.04.2007 Beiträge: 481
|
Verfasst am: 16.09.2007, 19:49 Titel: |
|
|
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...  |
|
Nach oben |
|
 |
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 16.09.2007, 20:36 Titel: |
|
|
Das Problem ist leicht gelöst...gar nicht.
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 |
|
 |
PMedia
Anmeldungsdatum: 14.08.2006 Beiträge: 2847
|
Verfasst am: 16.09.2007, 20:46 Titel: |
|
|
Man könnte prüfen ob die Fensterklasse existiert, was sich unter Windows als gar nicht mal so schwer erweist  |
|
Nach oben |
|
 |
dreael Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 2529 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 16.09.2007, 22:13 Titel: |
|
|
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 |
|
 |
PMedia
Anmeldungsdatum: 14.08.2006 Beiträge: 2847
|
Verfasst am: 16.09.2007, 22:57 Titel: |
|
|
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 |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4699 Wohnort: ~/
|
Verfasst am: 16.09.2007, 23:51 Titel: |
|
|
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 |
|
 |
AndT
Anmeldungsdatum: 02.04.2007 Beiträge: 481
|
Verfasst am: 17.09.2007, 08:38 Titel: |
|
|
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...  |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 17.09.2007, 13:05 Titel: |
|
|
Davon lässt sich windows nicht sonderlich beeindrucken...
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 |
|
 |
|