Laufende EXE mit externem Programm beenden

Sonstiges (nicht kategorisierbar)

Moderator: Moderatoren

Antworten
gf210957
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 101
Registriert: Mi, 21. Dez 2005 10:18

Laufende EXE mit externem Programm beenden

Beitrag von gf210957 »

Hallo an alle,

ich habe ein Problem mit einer Kundenanwendung. Auf dem Rechner läuft eine mit xBase++ 1.6 programmierte EXE, die von Zeit zu Zeit immer wieder beendet und neu gestartet werden muss. Diese Funktion muss automatisch vom System durchgeführt werden können. Da ich keinerlei Zugriff auf die EXE habe, habe ich versucht, diese über eine Batch-Datei bzw. den Scheduler zu beenden bzw. neu zu starten. Dies funktioniert jedoch leider bei mir nicht.

Kennt irgend jemand eine Möglichkeit, dieses Problem zu lösen?
Der Rechner läuft unter Win 98.

Ich bin für jede Lösung des Problems dankbar

Günter Früholz
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo Günter,
Da ich keinerlei Zugriff auf die EXE habe
Wie meinst du das? Hängt das Programm und muß deshalb beendet werden?

Probier mal PsKill von SysInternals (jetzt Microsoft).

http://www.microsoft.com/technet/sysint ... sKill.mspx

Als Voraussetzung wird zwar WinNT oder neuer genannt, vielleicht geht's aber trotzdem.

Alternativ dazu vielleicht KillProcess:
http://www.koeltzsch.com/Software/KillProcess.aspx

Viele Grüße
Günter
gf210957
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 101
Registriert: Mi, 21. Dez 2005 10:18

Beitrag von gf210957 »

Hallo Günter,

danke für Deine Antwort.
Leider funktioniert killprocess unter Win 98 auch nicht.
Ich gehe über Netzwerk auf einen entfernten Rechner, um Wartung und Datenpflege zu machen. Da dies um Mitternacht stattfindet, muss das Ganze ohne menschliche Eingriffe stattfinden. Leider kommt es häufiger vor, dass die auszutauschende EXE immer noch läuft, und somit ist der Austausch leider unmöglich.

Vielleicht gibt es noch eine andere Lösung.

Günter Früholz
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: Laufende EXE mit externem Programm beenden

Beitrag von AUGE_OHR »

hi,
gf210957 hat geschrieben: Auf dem Rechner läuft eine mit xBase++ 1.6 programmierte EXE, die von Zeit zu Zeit immer wieder beendet und neu gestartet werden muss.

Diese Funktion muss automatisch vom System durchgeführt werden können. Da ich keinerlei Zugriff auf die EXE habe
Bin mir jetzt nicht sicher was "keinerlei Zugriff auf die EXE" bedeuten soll,
deshalb 2 Antworten :

1.) In deiner "Main" hast du ja sicherlich eine AppEvent(). Der 4st Parameter
ist nun da für "timeout" zuständig und sendet dann ein "xbe_None"

2.) man kann "externe" Programme "abschiessen" mit folgender Funktion

Code: Alles auswählen

...
         CloseIt({"Nachricht lesen"     ,;
                  "Nachricht schreiben" ,;
                  "Nachrichten Eingang" ,;
                  "Nachrichten gesendet" })
...

FUNCTION  CloseIt( aNaam )
LOCAL i, nMax

nMax := LEN(aNaam)
FOR i = 1 To nMax
   CloseNow( aNaam[i] )
NEXT
RETURN NIL

#define WM_CLOSE        0x0010
#define WM_QUIT         0x0012

FUNCTION  CloseNow( cNaam )
LOCAL nEvent, mp1, mp2
LOCAL oDlg
LOCAL aTasklist
LOCAL aSize   := {0,0}
LOCAL aPos    := {0,0}
LOCAL lRunnin := .F.
LOCAL i
LOCAL nHwnd,cWind

oDlg := XbpDialog():new( AppDesktop(), , aPos, aSize, , .F.)
oDlg:clipSiblings := .T.
oDlg:drawingArea:ClipChildren := .T.
oDlg:create()

SETAPPFOCUS(oDlg)

aTasklist := GetTaskList( oDlg:gethWnd( ) )

FOR i = 1 to LEN( aTasklist )
    cWind := TRIM( UPPER( SUBSTR( aTasklist[i], 9 ) ) )
    cWind := SUBSTR( cWind, 1, LEN( cWind ) - 1 )
    If cWind == TRIM( UPPER( cNaam ) )
       lRunnin := .T.
       nHwnd := VAL( LEFT( aTasklist[i], 8 ) )

// hier wird nun die Application "abgeschossen"
///
       SendMessageA( nHwnd, WM_CLOSE ,0,0)
       RETURN lRunnin
    EndIf
Next

Return lRunnin

#include "DLL.ch"

#define GW_HWNDFIRST        0
#define GW_HWNDLAST         1
#define GW_HWNDNEXT         2
#define GW_HWNDPREV         3
#define GW_OWNER            4
#define GW_CHILD            5
#define GW_MAX              5

FUNCTION gettasklist( hWnd )
LOCAL aList:={}
LOCAL cWindowName
LOCAL nVisible
DO WHILE hWnd != 0
   cWindowname := space(100)
   IF ( getwindowtexta( hWnd, @cWindowName, LEN( cWindowName ) ) <> 0 )
       nVisible := IsWindowVisible(hWnd)
       IF nVisible == 1
          AADD( aList, Str( hWnd, 8 )+cWindowname )
       ENDIF
   ENDIF
   hWnd = GetWindow( hWnd, GW_HWNDNEXT )
ENDDO
RETURN aList

FUNCTION GetWindow( hWnd, uCmd )
LOCAL nDll:=DllLoad("USER32.DLL")
LOCAL xRet:=DllCall(nDll,DLL_STDCALL,"GetWindow", hWnd,uCmd)
DllUnLoad(nDll)
RETURN xRet

FUNCTION GetWindowTextA( hWnd, lPstring, nMax )
LOCAL nDll:=DllLoad("USER32.DLL")
LOCAL xRet:=DllCall(nDll,DLL_STDCALL,"GetWindowTextA", hWnd, @lPstring, nMax )
DllUnLoad(nDll)
RETURN xRet

FUNCTION IsWindowVisible( hWnd)
LOCAL nDll:=DllLoad("USER32.DLL")
LOCAL xRet:=DllCall(nDll,DLL_STDCALL,"IsWindowVisible", hWnd)
DllUnLoad(nDll)
RETURN xRet

Dabei entsprechen die Array Elemente von CloseIt() den Namen in der
Titleleiste (Titlebar := .T.) des Programm´s was du "abschiessen" willst.

Zu beachten ist, das deine Xbase++ Application nicht gerade Datei
operationen machen sollte wenn du es "abschiesst" ...
gf210957 hat geschrieben: "im Netzwerk" ...
ein Programm über das Netzwerk "abzuschiessen" wird damit nicht gehen.

gruss by OHR
Jimmy
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo,

der beste Weg sowas zu machen (geht übers Netzwerk und in allen BS), ist der, das Programm zu überreden sich selbst zu schließen ;-)

Von einer entfernten Station erstellst du (per hand oder per Programm eine Datei) z.B.:

RECHNERNAME.KILL

Dein Anwendungsprogramm prüft nun regelmäßig (über Timerevent oder in Eventloop ...) ob diese Datei existiert, wenn nein mach weiter, wenn ja beende das Programm. Der Vorteil liegt darin, dass du noch aufräumen kannst.
Gruß
Hubert
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16509
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hmmm,
ich würde das Programm sich selbst beenden lassen, wenn eine bestimmte Datei an einer bestimmten Stelle liegt.
In diesem Falle würde ich die Datei löschen und das Programm beenden und dabei den Errorlevel (z.B.) 15 zurückgeben.
Das Programm selber wird in einer Batch gestartet, die am Anfang ein Label setzt, dann das Programm aufruft. Danach wird der Errorlevel abgeprüft. Ist er nicht 15, wurde das Programm normal beendet. Ansonsten wird x Minuten gewartet und dann an das Anfangslabel gesprungen und somit das Programm wieder gestartet.
Für das Warten von 60 Sekunden nimmt man den folgenden Befehl:

Code: Alles auswählen

choice /C:* /T:*,60>nul
Man kann das ganze natürlich auch umdrehen, und den Errorlevel 15 nur dann zurückgeben, wenn es normal beendet wurde - somit kann man auch Abstürze abfangen...

Viele Grüße,
Martin


Hubert war schneller....
:grommit:
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.
gf210957
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 101
Registriert: Mi, 21. Dez 2005 10:18

Beitrag von gf210957 »

Hallo Jimmy,

danke für Deine Antwort.
Bei der Exe handelt es sich um ein Programm eines Fremdanbieters, der ständig unsere DBF anspricht. Um nun die DBF auszutauschen, muss die EXE beendet werden. Da das Ganze nicht lokal erfolgt, habe ich versucht auf dem Kundenrechner eine Batch Datei zu installieren, die das erledigt. Unter Win 2000 gibt es eine Kill.exe, die wunderbar funktioniert. Leider aber nicht mit Win 98.

Ein xBase++ Programm zur Erledigung scheidet leider auch aus, da im Programmverzeichnis bereits dlls aus einer älteren xBase Version (1.3 oder 1.6) vorhanden sind.

Kennst Du noch ein Programm, das unter Win 98 läuft.

Gruss

Günter Früholz
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo

@Jimmy,

funktioniert deine Routine auch unter Win98 ?

Wenn ja, muss man beide Vorschläge kombinieren:

Ein Programm schreiben, welches über die IsFile() Methode ferngesteuert wird. Diese kommt mit den DLL in ein eigenes Verzeichnis, dann hat man keine DLL Konflikte !

Dieses Programm ermittelt dann den Programmnamen (oder man gibt den vor, wenn man ihn weiß) und sendet den Close Befehl.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

gf210957 hat geschrieben:Unter Win 2000 gibt es eine Kill.exe, die wunderbar funktioniert. Leider aber nicht mit Win 98.
Also auf meinem Win2000 Rechner habe ich keine KILL.EXE ... hast du die von z.B. Sysinternals downgeloadet ? Wäre ja ab und zu ganz nützlich ;-)

Eines verwundert mich aber, du schreibst, das Programm eines Fremdanbieters nutzt die DBF eures Programmes. Eigentlich sollte man das nicht unterstützten, da hat man selbst nichts als Ärger, dass aber ihr das Problem lösen sollt verwundert mich. Der Fremdanbieter sollte sowas vorsehen ...
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Ein ganz anderer Ansatz ...

Beitrag von brandelh »

Hallo Günter,

man könnte eventuell auch eine Fernwartungssoftware installieren, dann kann der Anwender von seinem Arbeitsplatz die andere Software per Hand schließen. Ich nehme dafür RealVNC es gibt aber auch TinyVNC.

Im lokalen Netzwerk kann man unverschlüsselte Verbindungen nutzen, fürs Internet müsste man verschlüsselte nehmen.
Gruß
Hubert
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Beitrag von AUGE_OHR »

hi,
gf210957 hat geschrieben: Bei der Exe handelt es sich um ein Programm eines Fremdanbieters, der ständig unsere DBF anspricht.
nun kommen wir der Sache langsam näher ...
gf210957 hat geschrieben: Ein xBase++ Programm zur Erledigung scheidet leider auch aus, da im Programmverzeichnis bereits dlls aus einer älteren xBase Version (1.3 oder 1.6) vorhanden sind.
die DLLCALL´s sollten mit der Xbase++ v1.6 funktionieren
gf210957 hat geschrieben: Kennst Du noch ein Programm, das unter Win 98 läuft.
Frage : wird das "externe" Programm in der "Autoexec" gestartet ?
Wenn Nein, wie wäre es den einfach mit dem WIN98 "Tasktimer"
und folgenden BATch :

Code: Alles auswählen

C:\WINDOWS\RUNDLL32.EXE Shell32,SHExitWindowsEx 2
das "bootet" den PC dann bei der im "Tasktimer" eingestellten Zeit.
brandelh hat geschrieben: funktioniert deine Routine auch unter Win98 ?
JA. Ich habe die meisten Sachen noch für Win98 und manchmal damit
jetzt Probleme unter W2K/XP weil ich keine "User Rechte" habe ...

gruss by OHR
Jimmy
Antworten