Hi,
also ich habe Dokumente, die mit ihren Standardprogrammen per Runshell geöffnet werden.
Nun möchte ich aber, sobald das Programm geschlossen wurde, in meinem Programm einen Speichervorgang starten, also Änderungsdatum abspeichern.
Dafür wollte ich nun einen eigen Thread starten, der eben ständig prüft, ob die Exe schon beendet wurde.
Dabei habe ich eine Funktion getTasklist, die mir alle alle Handles Namen der offenen Fenster zurückgibt.
ich will einfach im Thread ständig nach der Exe in der Taskliste suchen und wenn sie nicht mehr gefunden wird, den Speichervorgang einleiten.
Nun wollte ich wissen, wie man aus einem Fensterhandle den Namen der "Exe" herausfindet?
Vielen Dank schon mal
prüfen, ob Programm läuft, bzw. beendet wurde [Erledigt]
Moderator: Moderatoren
-
- Rekursionen-Architekt
- Beiträge: 417
- Registriert: Mo, 17. Sep 2007 18:20
- Wohnort: Senftenberg
- Kontaktdaten:
prüfen, ob Programm läuft, bzw. beendet wurde [Erledigt]
Zuletzt geändert von stevie am Mo, 18. Mai 2009 11:27, insgesamt 3-mal geändert.
Viele Grüße
Stevie
Stevie
- Lewi
- 1000 working lines a day
- Beiträge: 830
- Registriert: Di, 07. Feb 2006 14:10
- Wohnort: Hamburg
- Danksagung erhalten: 2 Mal
Re: prüfen, ob Programm läuft, bzw. beendet wurde
Hallo Steve,
Wenn Du die Standard-Anwendungen kennst, mit denen die jeweiligen Dokumente aufgerufen werden
helfen Dir nachfolgende Funktionen weiter.
Solltest Du die jeweiligen Programme nicht kennen, die je Dokumententyp betriebssystemseitig eingestellt sind, lassen sich die Anwendungen jedoch über das Win-Api ermitteln.
Wenn Du die Standard-Anwendungen kennst, mit denen die jeweiligen Dokumente aufgerufen werden
helfen Dir nachfolgende Funktionen weiter.
Solltest Du die jeweiligen Programme nicht kennen, die je Dokumententyp betriebssystemseitig eingestellt sind, lassen sich die Anwendungen jedoch über das Win-Api ermitteln.
Code: Alles auswählen
If CheckisProgRunning( "winword.exe")
.... do this
else
.. do this
endif
Func CheckIsProgRunning( cExe, nPid )
Local lRet
Local lTerminate := .F
lRet := CheckProzessTask(cExe,nPid, lTerminate)
Return ( lRet )
DLLFUNCTION EnumProcesses(@lpidProcess,cb,@cbNeeded) USING STDCALL FROM PSAPI.DLL
DLLFUNCTION OpenProcess(dwDesiredAccess,bInheritHandle,dwProcessId) USING STDCALL FROM KERNEL32.DLL
DLLFUNCTION EnumProcessModules(hProcess,@lphModule,cb,@lpcbNeeded) USING STDCALL FROM PSAPI.DLL
DLLFUNCTION GetModuleBaseNameA(hProcess,hModule,@lpBaseName,nSize) USING STDCALL FROM PSAPI.DLL
DLLFUNCTION TerminateProcess(hProcess, uExitCode) USING STDCALL FROM KERNEL32.DLL
DLLFUNCTION CloseHandle(hObject) USING STDCALL FROM KERNEL32.DLL
#DEFINE PROCESS_QUERY_INFORMATION 1024
#DEFINE PROCESS_VM_READ 16
#define STANDARD_RIGHTS_REQUIRED (0x000F0000)
#define SYNCHRONIZE (0x00100000)
#define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF)
#define PROCESS_TERMINATE (0x0001)
/* Funktion zum Feststellen, ob ein Prozess (Programm) aktiv ist
/* gibt .T. zurück, falls ja
/* wenn lTerminate := .T., werden alle Instanzen des Prozesses gelöscht
/* Diese Funktion funktioniert auch, wenn ein Prozess kein Fenster hat und nicht auf der Taskleiste zu sehen ist
Function CheckProzessTask(cExe,nPidId, lTerminate)
Local aProcesses := space(10240)
Local aModules := space(4*10)
Local cbNeeded := 0
Local cbNeeded2 := 0
LOcal cname := space(64)
Local lIsKill := .F.
Local nPid
Local nProcHandle
Local i,nMax
LOcal hmod
Local xRet
Local lStillRunning := FALSE
EnumProcesses( @aProcesses, LEN(aProcesses) , @cbNeeded )
nMax := len(trim(aProcesses))/4
for i:= 1 to nMax
nPid := Bin2U(substr(aProcesses,1+((i-1)*4),4))
if nPidId==NIL .or. (nPIdId==nPid)
nProcHandle := OpenProcess( PROCESS_QUERY_INFORMATION + PROCESS_VM_READ ,0, nPid )
if nProcHandle > 0
if EnumProcessModules( nProcHandle, @aModules,len(aModules)/4, @cbNeeded2) != 0
cName := space(128)
GetModuleBaseNameA( nProcHandle,bin2u(substr(aModules,1,4)),@cName,len(cName))
cName := strtran(cname,chr(0),"")
CloseHandle(nProcHandle)
if upper(trim(cName)) == upper(cExe)
IF lTerminate
nProcHandle := OpenProcess(1,0,nPId)
xRet := TerminateProcess(nProcHandle,1)
CloseHandle(nProcHandle)
if xRet <> 0
sleep(100)
lIsKill := .T.
endif
ELSE
lStillRunninng := TRUE
EXIT
ENDIF
endif
endif
endif
endif
next
RETURN ( lStillRunning )
-
- Rekursionen-Architekt
- Beiträge: 417
- Registriert: Mo, 17. Sep 2007 18:20
- Wohnort: Senftenberg
- Kontaktdaten:
Re: prüfen, ob Programm läuft, bzw. beendet wurde
Also theroetisch geht die Funktion ja einwandfrei. Das Problem ist aber, dass der Stringvergleich immer schief geht. Ich übergebe einen String "WINWORD.EXE", der bekanntlich 11 Zeichen hat, was auch in der Funktion rauskommt, aber mein übergebener String wird grundsätzlich mit Länge 12 verglichen, wodurch cName == cExe fehlschlägt, trotz des absolut gleichen Textes.
Viele Grüße
Stevie
Stevie
- Martin Altmann
- Foren-Administrator
- Beiträge: 16509
- Registriert: Fr, 23. Sep 2005 4:58
- Wohnort: Berlin
- Hat sich bedankt: 111 Mal
- Danksagung erhalten: 48 Mal
- Kontaktdaten:
Re: prüfen, ob Programm läuft, bzw. beendet wurde
Hallo Stevie,
könnte das was mit der Stringterminierung "\0" bei der Rückgabe der API-Funktion zu tun haben?
Das strtran( ...chr(0), "" ) hast Du gesehen und übernommen?
Genauso wie das trim(..) vor dem endgültigen Vergleich?
Viele Grüße,
Martin
könnte das was mit der Stringterminierung "\0" bei der Rückgabe der API-Funktion zu tun haben?
Das strtran( ...chr(0), "" ) hast Du gesehen und übernommen?
Genauso wie das trim(..) vor dem endgültigen Vergleich?
Viele Grüße,
Martin
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/
Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
- Lewi
- 1000 working lines a day
- Beiträge: 830
- Registriert: Di, 07. Feb 2006 14:10
- Wohnort: Hamburg
- Danksagung erhalten: 2 Mal
Re: prüfen, ob Programm läuft, bzw. beendet wurde
Wenn Du den Funktionscode 1:1 übernimmst, dann sollte das Problem nicht auftreten. Ich habe die Funktion in Live-Anwendungen ohne das ich bisher irgendwelche User-Fehlermeldungen bekommen habe.
-
- Rekursionen-Architekt
- Beiträge: 417
- Registriert: Mo, 17. Sep 2007 18:20
- Wohnort: Senftenberg
- Kontaktdaten:
Re: prüfen, ob Programm läuft, bzw. beendet wurde
also ich habe jetzt die Funktion c_trim aus Phils' Ide benutzt, um den String an die Funktion zu übergeben, damit klappte es dann.
Viele Grüße
Stevie
Stevie