Seite 1 von 2

Anzahl gleichzeitiger Starts eigener Programme beschränken

Verfasst: 07.04.2012 01:31
von TheCube
Hallo.
Die Lösung um die eigene EXE nur einmal starten zu können kennt man ja (CreateMutex_() usw.)
Ich bauchte aber etwas, um dem DAU bei Bedarf die Ausführung von z.B. drei Instanzen zu erlauben, aber eben auch nicht mehr -
falls derjenige mal den Überblick verloren hat. /:->
So folgend (als konstruiertes Beispiel) habe ich es dann gelöst:

Code: Alles auswählen

PrgName.s = "MeinProgramm1.0"
#MaxRunning  = 3

*SHnd = OpenSemaphore_(#SEMAPHORE_ALL_ACCESS,0,@PrgName)

If *SHnd = #Null Or GetLastError_() <> 0
  MessageRequester("Info:", " OpenSemaphore failed!" +Chr(13)+Chr(13) + " Erstelle jetzt neue Semaphore ...." )
  *SHnd = CreateSemaphore_(#Null,0,#MaxRunning-1,@PrgName)
  If *SHnd <> 0 And GetLastError_() = #ERROR_ALREADY_EXISTS
    MessageRequester("Achtung:", " Konnte Semaphore nicht erstellen!")
    CloseHandle_(*SHnd) : End
  EndIf
Else
  If ReleaseSemaphore_(*SHnd,1,#Null) = 0   ; Semaphore +1
    MessageRequester("Achtung:", " Dieses Programm wurde schon zu oft gestartet!")
    CloseHandle_(*SHnd) : End 
  EndIf
EndIf  
; ----------------------------------------------------------------------------
hwnd = OpenWindow(0,#PB_Ignore,#PB_Ignore,200,100,"Test - " + Str(#MaxRunning) + " instances allowed")
TextGadget(0,10,10,100,20,"Hallo")
Repeat :  Until WaitWindowEvent() = #PB_Event_CloseWindow

WaitForSingleObject_(*SHnd,1) : CloseHandle_(*SHnd)

End
Frage1: Ist das so ok, oder kann man das besser lösen ?
Frage2: Kann ich den aktuellen Zählerstand der Semaphore ermitteln? (Für Info im Fenster wieviele Programminstanzen laufen z.B.)

Re: Anzahl gleichzeitiger Starts eigener Programme beschränk

Verfasst: 07.04.2012 10:28
von c4s
Hier wird NtQuerySemaphore_() vorgeschlagen:
http://stackoverflow.com/questions/2579 ... res-values

Ob es jedoch den Aufwand wert ist, musst du selbst entscheiden. :wink:

Re: Anzahl gleichzeitiger Starts eigener Programme beschränk

Verfasst: 07.04.2012 10:57
von Danilo
Nicht direkt zu Deiner Frage, aber eine kleine Anmerkung zu:
TheCube hat geschrieben:Die Lösung um die eigene EXE nur einmal starten zu können kennt man ja (CreateMutex_() usw.)
Die meisten einfachen Lösungen dafür können Probleme machen, inklusive die Codes,
die von Microsoft und in verschiedenen WinAPI-Büchern zu finden sind.

Hier ein ausführlicher Artikel von Dr. Joseph M. Newcomer dazu:
- Avoiding Multiple Instances of an Application (auf seiner Homepage)
- Avoiding Multiple Instances of an Application (bei codeproject)

Dabei können auch mit Mutex/Semaphore Probleme entstehen, wenn mehrere User/Desktops
angemeldet sind usw.
Interessanter Artikel zu dem Problem, weitere gute Artikel bei MVP Tips, Techniques, and Goodies auf seiner Homepage.

Re: Anzahl gleichzeitiger Starts eigener Programme beschränk

Verfasst: 07.04.2012 17:20
von TheCube
@c4s:
Interessant dies NtQuerySemaphore_(), wenn auch (wie beschrieben) nur max. eine "halboffizielle" Lösung
ohne Funktionsgarantie in der Zukunft. Leider hab ichs nicht drauf diesen C-Code beim Link in PB umzusetzen.
Und den Aufwand mich da durchzufummeln mache ich dann wirklich nicht. :freak:

@Danilo:
TheCube hat geschrieben:
Die Lösung um die eigene EXE nur einmal starten zu können kennt man ja (CreateMutex_() usw.)
Die meisten einfachen Lösungen dafür können Probleme machen, inklusive die Codes,
die von Microsoft und in verschiedenen WinAPI-Büchern zu finden sind.
Ich meinte damit:

Code: Alles auswählen

MutexName$ = "MeinProgramm1.0" : hMutex = CreateMutex_(0, 0, @MutexName$) 
If GetLastError_() = #ERROR_ALREADY_EXISTS : End : EndIf
Was hoffentlich in allen Szenarien ok ist.
Bei Querlesen gabs unter deinen Links eher Bedenken bei der Verwendung von Findwindow() (?)
Aber ansonsten informative Links :allright: .....

Re: Anzahl gleichzeitiger Starts eigener Programme beschränk

Verfasst: 07.04.2012 20:12
von Danilo
TheCube hat geschrieben:Ich meinte damit:

Code: Alles auswählen

MutexName$ = "MeinProgramm1.0" : hMutex = CreateMutex_(0, 0, @MutexName$) 
If GetLastError_() = #ERROR_ALREADY_EXISTS : End : EndIf
Was hoffentlich in allen Szenarien ok ist.
Scheinbar nicht bei mehreren Usern und mehreren Desktops etc., siehe meine Antwort (Zitat von Dr. Joseph M. Newcomer) im englischen Forum.

Re: Anzahl gleichzeitiger Starts eigener Programme beschränk

Verfasst: 07.04.2012 20:20
von ts-soft
Danilo hat geschrieben:Scheinbar nicht bei mehreren Usern und mehreren Desktops etc.,
Sehe ich das richtig, das dieses Problem nur zu trifft, wenn das Programm auf einem Server OS
läuft?
Dann kann man das Problem doch eher vernachlässigen, Server-Tauglichkeit ist ja kein Standard
bei Windows-Programmen.

Gruß
Thomas

Re: Anzahl gleichzeitiger Starts eigener Programme beschränk

Verfasst: 07.04.2012 20:34
von Nino
ts-soft hat geschrieben:
Danilo hat geschrieben:Scheinbar nicht bei mehreren Usern und mehreren Desktops etc.,
Sehe ich das richtig, das dieses Problem nur zu trifft, [...]
Wenn das Problem nur scheinbar existiert, braucht man sich eh nicht drum zu kümmern. :mrgreen:

Re: Anzahl gleichzeitiger Starts eigener Programme beschränk

Verfasst: 07.04.2012 20:46
von Danilo
ts-soft hat geschrieben:
Danilo hat geschrieben:Scheinbar nicht bei mehreren Usern und mehreren Desktops etc.,
Sehe ich das richtig, das dieses Problem nur zu trifft, wenn das Programm auf einem Server OS läuft?
Ich glaube nicht, da auch auf einem normalen Windows mehrere User gleichzeitig eingeloggt sein können
und man zwischen den Users wechseln kann, während Programme laufen.

Gedachtes Beispiel: Du (Admin) gehst kurz vom PC weg, Deine Frau (User) loggt sich in der Zwischenzeit ein
und kann dann ein Programm nicht starten, weil Du es auch am laufen hast und CreateMutex
bei Deiner Frau dann schiefgeht wg. unterschiedlicher Rechte...??

Auch kann man selbst als SingleUser neue Desktops erstellen, aber damit habe ich bisher nur einmal
kurz rumprobiert, wegen einem Code von KCC im engl. Forum. Ich benutze selbst nur einen Account
und einen Desktop, hatte vor vielen Jahren mal DesktopSwitcher benutzt (ich kann nur vermuten das
man sowas auch mit CreateDesktop erzeugt, denn genau das passierte hier beim probieren mit dem KCC Code).

Ich habe bisher davon auch keine Ahnung (deshalb das "scheinbar", Nino ;)), muss das auch erst testen, nachlesen und ausklüngeln. :D

Es ist also evtl. (anscheinend 8)) etwas komplizierter, gerade bei CreateDesktop/SwitchDesktop (die man mit unterschiedlichen Rechten erstellen kann).
He points out that it is possible to use API calls such as LogonUser, CreateProcessAsUser, CreateDesktop and SwitchDesktop,
and therefore it is possible to have multiple users and multiple desktop sessions running under different accounts.

Re: Anzahl gleichzeitiger Starts eigener Programme beschränk

Verfasst: 07.04.2012 21:54
von TheCube
Also unter Win7x86 mit zwei Konten (1x Administrator, 1x Standarduser)
funktionieren beide Versionen einwandfrei, die User sind wohl diesbezüglich strikt getrennt.
Starte ich in einem User die Semaphorenvariante 3x kann ich es im anderen Konto ebenso max. 3x tun.
Vergleichbares für die Mutex-Variante: Jeder User darf das Program 1x am laufen haben.
Naja ... schön für die Frau die sich an meinem Rechner einloggt (gruseliger Gedanke :lol: ), aber blöd das
mich ein User so austricksen kann. >_< Es gibt eben Dinge die besser nur einmal pro PC laufen sollten.

Re: Anzahl gleichzeitiger Starts eigener Programme beschränk

Verfasst: 07.04.2012 22:07
von Danilo
TheCube hat geschrieben:... aber blöd das mich ein User so austricksen kann. >_<
Es gibt eben Dinge die besser nur einmal pro PC laufen sollten.
Genau dazu sind die Flags bei Dr. Newcomers Code da:

Code: Alles auswählen

SI_SESSION_UNIQUE                        - Allow one instance per login session
SI_DESKTOP_UNIQUE                        - Allow one instance per desktop
SI_TRUSTEE_UNIQUE                        - Allow one instance per user account
SI_SESSION_UNIQUE | SI_DESKTOP_UNIQUE    - Allow one instance per login session,
                                           instances in different login sessions
                                           must also reside on a different desktop
SI_TRUSTEE_UNIQUE | SI_DESKTOP_UNIQUE    - Allow one instance per user account,
                                           instances in login sessions running a
                                           different user account must also reside    
                                           on different desktops.
SI_SYSTEM_UNIQUE                         - Allow only one instance on the whole system
Siehe letztes Flag, SI_SYSTEM_UNIQUE.

Die C-Variante sollte auch wirklich sehr einfach nach PB übersetzt werden können, sind ja nur ein paar Zeilen.
Habe aber gerade keine Nerven dazu, bin schon zu müde.

Ich denke seine Variante ist sehr gut, deshalb hier der Hinweis. Schadet ja nicht sowas
im CodeArchiv zu haben, wenn es sicherer ist und man besser bestimmen kann, was
"single instance" eigentlich bedeutet (system, user, desktop).

Das sollte man dann auch genauso für Deine benannte Semaphore umsetzen können,
da es in dem Code letztendlich nur um die Erzeugung von eindeutigen Namen geht (statt CreateXXX_(0,0,@"MeinProgramm1.0")).