Wollen wir jedoch eine komplette Applikation aus dem Arbeitsspeicher entfernen oder einfach nur überprüfen, ob eine Anwendung bereits aktiv ist, dann können wir diese Prüfung nicht mit PEMSTATUS() durchführen.
Bereits im April und Dezember habe ich in meinen Postings zur Druckerstatus Abfrage die Windows Management Instrumentation eingesetzt. Jetzt kommt sie erneut zum Einsatz, um uns Prozessinformationen zu liefern.
Die unten stehende Demofunktion 'TerminateProcess()' dient dem gezielten Entsorgen von unerwünschten Prozessen. Im Bereich der Singleton Patterns ist dies nicht immer die gewünschte Vorgehensweise. Aus diesem Grund verfügt die Funktion auch über Parameter, mit denen gezielte Abfragen und Ansichten ohne Prozesslöschung durchgeführt werden können.
Wird bspw. als einziger Parameter der Programmname übergeben erfolgt eine automatische Löschung sämtlicher gefunden Prozesse dieser Applikation. Die beiden Funktionstests zeigen mögliche unterschiedliche Parametrisierungen auf.
* // Funktionstest 1
* // - Anzahl vorhandener Prozesse zurückmelden
RUN /n notepad.exe
RUN /n notepad.exe
RUN /n notepad.exe
liAnzahl = TerminateProcess( [notepad.exe] , .T. )
CLEAR
? [gefundene Prozesse: ]
?? liAnzahl
* // Funktionstest 2
* // - alle gefundenen Prozesse entsorgen
* // Alternativer Aufruf um gefundene Prozesse anzuzeigen
* liAnzahl = TerminateProcess( [notepad.exe] , .F. , .F. , .T. )
liAnzahl = TerminateProcess( [notepad.exe] )
? [beendete Prozesse: ]
?? liAnzahl
FUNCTION TerminateProcess as Integer
LPARAMETERS vAppname as String, vJustCheck as Boolean, vAllButLast as Boolean, vBrowseLast as Boolean
* // Funktion zum löschen/melden von Prozessen übergebener Programmnamen
* //
* // Parameter Variable Status
* // #1 vAppname optional (default = Aktuelles Programm)
* // Name der Programmdatei
* // #2 vJustCheck optional (default = .F.)
* // Nicht löschen, nur Melden
* // #3 vAllButLast optional (default = .F.)
* // Letzen Prozess nicht löschen
* // #4 vBrowseLast optional (default = .F.)
* // Gefundene Prozesse anzeigen
vAppname = EVL( vAppname , PROGRAM() )
vAllButLast = EVL( vAllButLast , .F. )
vBrowseLast = EVL( vBrowseLast , .F. )
* // Deklaration und Belegung benötigter Arbeitsvariablen. Hierbei
* // erfolgt bei den zwei Objekt-Variablen eine direkte Referenzierung
* // auf das WMI-Objekt sowie das Abfrageergebnis
LOCAL liReturn as Integer, liCount as Integer , llExit as Boolean, ;
lcLogname as String , lcComputer as String, ;
loCIMV2 as Object, loProcCols as Object, lcOwner as String
liReturn = 0
liCount = 0
llExit = .F.
lcLogname = ALLTRIM( GETWORDNUM( SYS( 0 ) , 2 , [#] ) )
lcComputer = [.]
TRY
loCIMV2 = GETOBJECT( [winmgmts:{impersonationLevel=impersonate}!\\] + lcComputer + [\root\cimv2] )
loProcCols = loCIMV2.ExecQuery( [select * from Win32_Process where name='] + vAppname + ['] )
CATCH
llExit = .T.
ENDTRY
IF !llExit
* // Arbeitscursor erstellen und die WMI Objekte verarbeiten
CREATE CURSOR crsTasks ( ProgOwner c( 30 ) , ProgName c( 30 ) , ProgPath c( 200 ) )
FOR EACH objProcess in loProcCols
liCount = liCount + 1
lcOwner = SPACE( 256 )
= objProcess.GetOwner( @lcOwner )
m.ProgOwner = lcOwner
m.ProgName = objProcess.Name
m.ProgPath = EVL( objProcess.ExecutablePath , [-] )
INSERT INTO crsTasks FROM MEMVAR
ENDFOR
* // Ggf. die gefundenen Prozesse angezeigen (Parameter #4)
IF vBrowseLast
BROWSE LAST
ENDIF
IF !vJustCheck
* // Die gefundenen Prozesse der Reihe nach entsorgen
FOR EACH objProcess in loProcCols
liReturn = liReturn + 1
* // Wenn der letzte Prozess beibehalten werden soll (Parm.#3)
* // dann raus aus der Schleife, andernfalls geht's weiter bis
* // zum bitteren Ende... ;-)
IF vAllButLast AND liReturn = liCount
EXIT
ELSE
SELECT crsTasks
GO ( liReturn )
IF ALLTRIM( crsTasks.ProgOwner ) == lcLogname
objProcess.Terminate( 0 )
ENDIF
ENDIF
ENDFOR
ELSE
liReturn = liCount
ENDIF
* // Arbeitscursor entsorgen, WMI-Objektreferenzen auflösen
USE IN SELECT( [crsTasks] )
loCIMV2 = .NULL.
loProcCols = .NULL.
ENDIF
* // Anzahl der gelöschten/gefundenen Prozesse zurückgeben
RETURN liReturn
ENDFUNC
Weitere Aufrufmöglichkeiten:
Löscht alle Prozesse des übergebenen Programms, der letzte Prozess bleibt jedoch bestehen
liAnzahl = TerminateProcess( [notepad.exe] , .F. , .T. )
Löscht alle Prozesse des übergebenen Programms, zeigt jedocht zuvor eine Liste der gefundenen Prozesse an
liAnzahl = TerminateProcess( [notepad.exe] , .F. , .F. , .T. )
Keine Kommentare:
Kommentar veröffentlichen