Programmstatus 'Keine Rückmeldung' ermitteln

Hallo zusammen

Ich starte ein Programm über shell und möchte periodisch überprüfen, ob das Programm noch normal läuft, bzw. ob es den Status „Keine Rückmeldung“ erreicht hat.

Ich hab zwar rausgefunden, wie ich überprüfen kann, ob das Programm überhaupt noch läuft, aber leider nicht wie ich an den Status „Keine Rückmeldung“ herankomme.

Gibt es hierfür ein API das mir entgangen ist, oder weiss jemand wie der Taskmanager das ermittelt?

Allerbesten Dank für eure Antworten.
Viele Grüsse
Patrick

Hallo Patrick,

‚keine Rückmeldung‘ bedeutet nur, daß das Programm rechnet und nicht zwischendurch die Steuerung an Windows übergibt. Das Programm arbeitet also nur, das ist nichts worauf man reagieren muß.

Zu Deiner eigentlichen Frage, nein, ich habe keine Ahnung, wie man das ermittelt.

Gruß, Eainer

Hallo Rainer

Danke für die Antwort. Der Sinn meines Programmes ist es eben, dass der Benutzer eine Benachrichtigung erhält, sobald der betreffende Task nicht mehr ausgelastet ist.

Ich habe inzwischen einen Ansatz mit dem Senden eines Mausklicks mithilfe von sendmessage (API) auf das betreffende Fenster der „Keine Rückmeldung“-Applikation gefunden: Der Sendmessagebefehl kann nämlich solange nicht abgearbeitet werden, bis das betreffende Programm wieder übrige Rechenzeit hat. Dumm nur, dass während des Abwartens des Sendmessagebefehls auch meine Applikation absolut blockiert wird …

Werde mal weiterschauen, aber weitere Ideen natürlich erwünscht :wink:

Gruss
Patrick

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallon,

Dumm nur, dass während des Abwartens des
Sendmessagebefehls auch meine Applikation absolut blockiert
wird …

Dies koennteman umgehen, indem du den SendMessage-Befehl auf einen eigenen Thread setzt.

tschau
Peter

Hallo,

Ich starte ein Programm über shell und möchte periodisch
überprüfen, ob das Programm noch normal läuft, bzw. ob es den
Status „Keine Rückmeldung“ erreicht hat.

eine Frage habe ich dazu noch.
Ist das ein Programm, das Du verändern kannst? Hast Du den Quellcode?

Deine Frage erinnert mich an ein Problem, das ich mal hatte, gelegentlich hat sich ein Programm einfach ‚aufgehängt‘.

Das Programm hat auf eine Datei gewartet, die ein anderes Programm geschrieben hat, diese per FTP gelesen und ausgewertet. Wenn das Lesen und Schreiben zufällig gleichzeitig passiert sind, hat sich das Programm aufgehängt.

Ich habe dann in dieses Programm einen Timer eingebaut, der mir in die Titelzeile die Zeit geschrieben hat. Wenn das Programm hängen geblieben ist wurde die Zeit nicht mehr aktualisiert und das Überwachungsprogramm konnte das Programm stoppen und neu starten.

Leider hat aber auch das nicht zuverlässig genug gearbeitet. Ich habe inzwischen eine komplett andere Lösung, die die Überwachung überflüssig macht.

Gruß, Rainer

Hallo Rainer

Am Programm, dass sich aufhängt kann ich nicht’s manipulieren. Aber ich habe inzwischen eine andere, praktische Lösung gefunden:

Ich habe ein 2. VB-Progrämmlein erstellt dem ich als Argument das Handle des zu überwachenden Fensters übergebe. Dieses hat kein GUI sondern lediglich ein Codemodul mit dem es einen Sendmessage-Call an das per Argument übergebene zu überwachende Fenster zu senden und sich danach selber zu beenden (hört sich vielleicht kompliziert an, hat aber nur ca. 20 Codezeilen benötigt). Nun kann ich im Hauptprogramm bequem periodisch über einen Timer ermittlen, ob der ‚Agent‘ noch aktiv ist.

Ist der ‚Agent‘ noch aktiv, wartet dieser auf das abarbeiten des Sendmessage-Calls, ergo das überwachte Programm ist zur Zeit noch ausgelastet. Der ‚Agent‘ ist während dieser Zeit zwar ebenfalls ausgelastet, aber das muss die Hauptanwendung ja nicht kümmern.

Ist der ‚Agent‘ nicht mehr aktiv (Task wurde beendet), wurde der Sendmessage-Call ausgeführt und das überwachte Programm ist somit wieder verfügbar. Der Benutzer kann entsprechend informiert werden.

Natürlich ist’s ein wenig schade, dass ich nun 2 Exe-Dateien ausliefern muss, aber das Prinzip funktioniert tadellos und die ‚Agenten-Exe‘ ist auch nur grad 16K gross :wink:

Das ganze Problem liegt wahrscheinlich darin, dass VB6 scheinbar nur einen Thread pro Task zur Verfügung stellt und deshalb immer gleich das gesamte Programm blockiert, sobald die Abarbeitung des Codes ins stocken gerät (wie in meinem Fall das Abwarten eines API Calls, selbst die Timer stellen während dieser Zeit ihre Arbeit ein …). Oder ich habe bisher einfach nicht rausgefunden wie in VB6 richtige asynchrone Prozesse auf die Beine gestellt werden können …

Auf jeden Fall nochmals besten Dank und
Gruss
Patrick

Hallo Peter

Das hört sich ganz interessant an, und wie funktioniert das mit VB6? Ich hab’s mit Timern versucht, das scheint aber nicht der richtige Weg zu sein …

Ein kleine Beispiel könnte meine momentane Lösung perfektionieren.
Da bin ich aber mal gespannt =)

Besten Dank und
viele Grüsse
Patrick

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hi Patrick,

Aber ich habe inzwischen eine andere, praktische Lösung
gefunden:

wunderbar! Das freut mich.

Natürlich ist’s ein wenig schade, dass ich nun 2 Exe-Dateien
ausliefern muss, aber das Prinzip funktioniert tadellos und
die ‚Agenten-Exe‘ ist auch nur grad 16K gross :wink:

Das würde mich am wenigsten stören, Hauptsache, es funktioniert.

Das ganze Problem liegt wahrscheinlich darin, dass VB6
scheinbar nur einen Thread pro Task zur Verfügung stellt …

Ja, VB6 ist nicht Multitreadfähig. Es gibt nur einen Thraed. Mit einem gigantischen Aufwand läßt sich zwar auch ein weiterer Prozess starten, aber das habe ich nicht ganz verstanden, war mir zu hoch. Gelesen habe ich darüber bei http://www.ActiveVB.de dort weiß Jemand, wie es geht … :smile:

Gruß, Rainer

Hallo Rainer,

da muss ich dir ein wenig wiedersprechen :frowning:
Wenn du sturr eine function nach der anderen ausführst, so arbeitest du nur in einen Thread. Natürlich kannst du unter VB, also in deinem Program mehrere Threads zur Verfügung stellen! Das sagte aber bereits schon Peter :smile:
Der Aufruf ist garnicht mal kompliziert, dennoch sollte man es vermeiden in einen programm zig threads zu starten.
Wenn du wissen magst, wie es geht, so gebe mal bescheid und ich poste dir dann den Source. Ganz aus dem Kopf weiss ich es nicht mehr ( Sonst würde ich es gleich posten), von daher muesste ich erst auch nachschauen.

MfG Alex

Hallo Patrick,

ich kann ja mal fix schauen ob ich es auf Anhieb finde, wie es geht.
Mit Timern ist def. der falsche Weg :wink:

MfG Alex

Hallo Patrick,

also nach langem suchen, habe ich dennoch nichts gefunden. Aber ich habe mal kurz was probiert und siehe da es ging :wink:

Also um einen Thread zu erstellen gehe wiefolgt vor.
Lege ein Modul an
Zu Testzwecken erstelle auf der Form ein Label ( Label1) Dazu noch eine Textbox und ein Button ( Command1)
Wenn du den Button klickst, wird der Thread gestartet. Diese ändert den Text im Label1 aller 1 Sekunde von 0 auf 1 auf 0 auf 1 etc.
Dennoch kannst du ohne weiteres, in der Textbox schreiben! Von daher erkennst du das das ändern des Labels der Thread macht.

Ich selbst habe aber nur das nötigste geschrieben. An deiner Stelle würde ich mich mal ein wenig in die Materie einlesen. Gerade wie man Threads beendet, oder Terminiert. Aber lange Rede kurzer Sinn. Hier der Source

'Code im Modul
Option Explicit

Declare Function CreateThread Lib "kernel32" (ByVal lpSecurityAttributes As Long, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, ByVal lpParameter As Long, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Declare Function SetThreadPriority Lib "kernel32" (ByVal hThread As Long, ByVal nPriority As Long) As Long
Public Declare Function ResumeThread Lib "kernel32" (ByVal hThread As Long) As Long

Private Function RunThread() As Long 
'Hier dein Code! Der andere Code ist nur als Demo!
On Error Resume Next
Dim x As Boolean
 Do
 If x Then
 Form1.Label1 = "1"
 Else
 Form1.Label1 = "0"
 End If
 Sleep (1000)
 x = Not (x)
 Loop
End Function

Public Function ThreadExecute() As Long 
Dim hWatch As Long
Dim hWatchID As Long
 hWatch = CreateThread(ByVal 0, 2000, AddressOf RunThread, ByVal 0&, &H4, hWatchID)
 SetThreadPriority hWatch, 0
 ResumeThread hWatch
 Call CloseHandle(hWatch)
 ThreadExecute = hWatchID
End Function

'Code in der Form1
Option Explicit

Private Sub Command1\_Click()
 Call ThreadExecute
End Sub

Achte aber darauf. Du musst eine Funktion nehmen die deine Aktion ausführt. Sonst funktioniert der Aufruf von Addressof RunThread nicht!
Deswegen muss der Code auch in einem Modul stehen.Auch musst die Anweisung Addressof in CreateThread stehen haben. Du kannst sie nur über Umwege einer Variablen zuweisen. Diese koenntest du dann alternativ auch der API übergeben.
Willst du die Adresse der Funktion einer Variablen zuweisen, so freunde dich folgender Routine an

Private Function Addr2Long(ByVal Addr As Long) As Long
 Addr2Long = Addr
End Function

'Aufruf:
Dim Var as Long
Var = Addr2Long(AddressOf RunThread)

Sodele das sollte es gewesen sein :smile: Achso, wenn du das einbaust, so speichere dein Project vor jedem Testlauf, denn wenn du den Thread gestartet hast und nicht beendet, so schmiert dir dein VB ab :frowning:

MfG Alex

Hi Alex,

da muss ich dir ein wenig wiedersprechen :frowning:

OK, wenn ich Unfug schreibe, korrigiere mich ruhig.

Wenn du sturr eine function nach der anderen ausführst, so
arbeitest du nur in einen Thread. Natürlich kannst du unter
VB, also in deinem Program mehrere Threads zur Verfügung
stellen! Das sagte aber bereits schon Peter :smile:

Hab ich ja auch, aber eben nicht ohne API-Aufrufe, die wenigstens so kompliziert sind, daß ich mir den Code nicht merken kann. Mir ist das zu kompliziert, aus dem Kopf kann ich das nicht. :frowning:

Der Aufruf ist garnicht mal kompliziert, dennoch sollte man es
vermeiden in einen programm zig threads zu starten.
Wenn du wissen magst, wie es geht, so gebe mal bescheid und
ich poste dir dann den Source. Ganz aus dem Kopf weiss ich es
nicht mehr ( Sonst würde ich es gleich posten), von daher
muesste ich erst auch nachschauen.

*gg* Wenn Du das aus dem Kopf nicht kannst, ist es nach meiner Auffassung kompliziert. :smile:

Nein, ich habe z.Z. keinen Bedarf, ein Prozess reicht für mich völlig aus.

Gruß, Rainer

Hi Alex,

das sieht ja wirklich nicht so kompliziert aus. Ich hab’ mal eine FAQ daraus gemacht. :smile:

Gruß, Rainer

Ist es auch nicht :smile: Du musst nur mal schauen, welche Parameter du bei CretaThread übergibst. In diesem Falle habe ich bsp. H4 übergeben, was bedeutet das der Thread Suspend Mode gestartet wird. Ergo noch nicht läuft. Das machte ich um nochmal schnell zu zeigen das man dann man SetThreadProirity die Priorität des Threads setzen kann. Der Eigentlich Thread wird dann über ResumeThread gestartet :wink:
Wenn du diese Daten aber nicht brauchst, so schreibe in der API CreateThread einfach anstatt der &H4 eine 0 und der Thread wird sofort normal gestartet, welches zur Folge hat das die anderen 2 API (Setthreadpriority und Resumethread)erst garnicht aufrufen musst :wink:

Aber anbei, wenn ich einmal dabei bin, können wir ja mal die einzelnen Flags auseinandernehmen

Declare Function CreateThread Lib "kernel32" (ByVal lpSecurityAttributes As Long, \_
ByVal dwStackSize As Long, \_
ByVal lpStartAddress As Long, \_
ByVal lpParameter As Long, \_
ByVal dwCreationFlags As Long, \_
lpThreadId As Long) As Long

lpSecurityAttributes:
Setze 0 so dass der Thread die Standard-Sicherheiteinstellungen benutzen soll. Ansonsten benutze die Declaration

Public Type SECURITY\_ATTRIBUTES
 nLength As Long
 lpSecurityDescriptor As Long
 bInheritHandle As Boolean
End Type

fülle Sie mir den gewünschten Daten und übergibt dann einen Zeiger auf diesen Typ :smile:


dwStackSize:
spezifiziert die Stackgröße des Threads. Wenn du dem Tread die selbe Stackgröße wie dem Hauptthread geben willst, benutze 0 als Parameter, ansonsten die Grösse.


lpStartAddress:
Hier die Adresse der Function übergeben, die aufgerufen wird! Es muss sich um eine Funktion handeln und diese muss in einen Modul liegen!
Die Adresse einer Funktion kannst du nicht direkt einer Variablen zuweisen! Willst du dies machen, so verwende folgende Dummy Funktion.

Dim Var as Long
Private Function Addr2Long(ByVal Addr As Long) As Long
 Addr2Long = Addr
End Function
'Aufruf:
Var = Addr2Long(AddressOf TestWndProc)

Nun kannst du auch die Variable Var mit übergeben.
Man sagt das die Function die aufgerufen wird, eigentlich ein Argument von 32 Bit verlangt und ein Argument von 32 Bit zurückliefern muss. 
Aber bei meinen Tests, war dies nicht erforderlich :/
Ansonsten gestalte den Aufruf zum Bsp. so

Private Function RunThread(p as Long) as long
 'Dein Code
End Function

Hierbei vernachlässige nun einfach den Parameter p und liefere eine 0 zum bsp. zurueck bei erfolgreichen Aufruf :wink:

lpParameter:
Der Parameter, den du der Thread-Funktion übergeben möchtest.

dwCreationFlags:
&H4 -\> Suspend Mode
&H0 -\> Normal

0 bedeutet das der Thread sofort nach seiner Erzeugung zu laufen beginnt. Das Gegenteil ist das CREATE\_SUSPENDED Flag.Dort wartet der Thread mit dem starten solange bis ResumeThread aufgerufen wurde.

lpThreadId:
Die CreateThread-Funktion füllt die Thread ID des neu erzeugten Threads an dieser Adresse

Ist der Aufruf erfolgreich so bekommst du das ThreadHandle zurueckgeliefert. Wenn nicht dann eine 0!

So nun nochmal schnell zur API SetThreadPriority

Public Declare Function SetThreadPriority Lib "kernel32" (ByVal hThread As Long, \_
ByVal nPriority As Long) As Long

hThread = Das Handle des Threads welcher gestartet werden soll
nPriority = Priorität (siehe Liste)

THREAD\_PRIORITY\_LOWEST = -2&
THREAD\_PRIORITY\_HIGHEST = 2&
THREAD\_PRIORITY\_ABOVE\_NORMAL = (THREAD\_PRIORITY\_HIGHEST - 1&amp:wink:
THREAD\_PRIORITY\_BELOW\_NORMAL = (THREAD\_PRIORITY\_LOWEST + 1&amp:wink:
THREAD\_PRIORITY\_IDLE = -15&
THREAD\_PRIORITY\_NORMAL = 0&
THREAD\_PRIORITY\_TIME\_CRITICAL = 15&
THREAD\_PRIORITY\_ERROR\_RETURN = &H7FFFFFFF

MfG Alex

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hi Alex,

danke! Wunderbar!

Nun fehlt nur noch das saubere Ende. :smile:
Ich habe schon ein wenig in der API-Guide gewühlt, ein Beispiel gebastelt … ich schaffe es (noch) nicht, das Programm zu beenden, ohne daß die Entwicklungsumgebung abstürzt. :frowning:

Gruß, Rainer

'Form:
Option Explicit

Private Sub Command1\_Click()
 hThread = CreateThread(ByVal 0&, ByVal 0&, \_
 AddressOf AsyncThread, ByVal 0&, ByVal 0&, hThreadID)
 CloseHandle hThread
End Sub
Private Sub Form\_Unload(Cancel As Integer)
 TerminateThread hThread, 0
End Sub


'Modul:
Option Explicit

Public Declare Sub Sleep Lib "kernel32" \_
(ByVal dwMilliseconds As Long)
Public Declare Function CreateThread Lib "kernel32" \_
(lpThreadAttributes As Any, ByVal dwStackSize As Long, \_
ByVal lpStartAddress As Long, lpParameter As Any, \_
ByVal dwCreationFlags As Long, lpThreadID As Long) As Long
Public Declare Function TerminateThread Lib "kernel32" \_
(ByVal hThread As Long, ByVal dwExitCode As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" \_
(ByVal hObject As Long) As Long
Public hThread As Long, hThreadID As Long
Public Sub AsyncThread()
 Dim n As Byte
 'Let this thread sleep for 1 second
 While n 

Gruß, Rainer

Hallo Rainer,

Threads musst du nicht direkt beenden. Sie beenden sich von selbst!
Das Problem liegt darin das wenn etwas in dem Thread noch ausgefuehrt wird, dann VB abschmiert :frowning:
Du kannst Thread voruebergehend anhalten ( Auf Eis legen) Aber auch wenn du dann VB beendest, schmiert es dir ab. Ergo du musst vorher zwingend den Thread beenden!

Um mal wieder auf das ursprüngliche Posting zu kommen.
Er soll in dem Thread die Sendmessage API senden!
Solange bleibt er ja im Thread stehen. Irgendwann kommt er dann ja wieder zurueck ( Sendmessage hat abgearbeitet) So setzt er nun ein Flag das VB beendet werden kann.

Bsp:

'Im Modul
Public InProgress as Boolean
Private Function RunThread(p as long) as long
InProgress=True
 'Hier seine Sendmessage nachricht schicken
InProgress=False

' In der Form
Private Sub Beenden\_Click()
If InProgress then
 Msgbox " Program kann noch nicht beendet werden, da noch aktivitäten ausgeführt werden",vbcritical
else
 unload me
end if
End Sub

Aber zur Veranschaulichung poste ich dir mal ein kleines Demo, was die wirkungsweise veranschaulicht.

Erstelle ein Modul, Eine Form (Form1).
Auf die Form packe folgende Steuerelemente
Eine Checkbox -> Caption Suspend / Auf Eis legen / Thread anhalten
3 Command Button
Button 1 -> Start Thread
Button 2 -> Stop Thread
Button 3 -> Mach irgendwas
Dazu noch 2 Pictureboxen
Picture 1 -> Aktionen werden vom Thread angezeigt
Picture 2 -> Vb malt drinnen rum :wink:

Sodele dann kopiere mal folgenden Code ins Project

'Im Modul
Option Explicit

Declare Function CreateThread Lib "kernel32" (ByVal lpSecurityAttributes As Long, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, ByVal lpParameter As Long, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long
Public Declare Function SetThreadPriority Lib "kernel32" (ByVal hThread As Long, ByVal nPriority As Long) As Long
Public Declare Function ResumeThread Lib "kernel32" (ByVal hThread As Long) As Long
Public Declare Function Ellipse Lib "gdi32" (ByVal hdc As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Public Declare Function SuspendThread Lib "kernel32" (ByVal hThread As Long) As Long

Public ThreadIsRunning As Boolean
Public ThreadBeenden As Boolean
Public WatchTHID As Long
Public hWatchTH As Long

Public Const CREATE\_SUSPEND = &H4
Public Const THREAD\_PRIORITY\_IDLE = -15
Public Const THREAD\_PRIORITY\_TIME\_CRITICAL = 15
Public Const THREAD\_PRIORITY\_NORMAL = 0

Public Function ThreadExecute(p As Long) As Long
 While Not ThreadBeenden
 Form1.Picture1.ForeColor = QBColor(Int(14 \* Rnd))
 Ellipse Form1.Picture1.hdc, Rnd \* 150, Rnd \* 150, Rnd \* 150, Rnd \* 150
 Wend
 Form1.Command1.Enabled = True
 Form1.Command2.Enabled = False
 Form1.Command3.Enabled = True
 Form1.Check1.Enabled = False
 ThreadExecute = 1
End Function

Public Function RunThread() As Boolean
 Form1.Command1.Enabled = False
 Form1.Command2.Enabled = True
 Form1.Check1.Enabled = True
 hWatchTH = CreateThread(ByVal 0&, 0, AddressOf ThreadExecute, ByVal 0&, CREATE\_SUSPEND, WatchTHID)
 SetThreadPriority hWatchTH, THREAD\_PRIORITY\_NORMAL
 ThreadBeenden = False
 ResumeThread hWatchTH
 RunThread = True
End Function

' In der Form1
Option Explicit


Private Sub Check1\_Click()
 If Check1.Value = 0 Then
 ResumeThread hWatchTH
 Else
 SuspendThread hWatchTH
 End If
End Sub

Private Sub Command1\_Click()
 Call RunThread
End Sub

Private Sub Command2\_Click()
 ThreadBeenden = True
End Sub

Private Sub Command3\_Click()
 Dim i&
 For i = 1 To 10000
 Picture2.ForeColor = QBColor(Int(14 \* Rnd))
 Ellipse Picture2.hdc, Rnd \* 150, Rnd \* 150, Rnd \* 150, Rnd \* 150
 Next i
End Sub

Private Sub Command4\_Click()
 Unload Me
End Sub

So nun starte mal das prog und klicke ein wenig rum.
Speichere das Projecjt aber vorher!

1:Thread starten -> Exit klicken
2:Thread starten -> Stopp klicken
3:Thread starten -> Checkbox klicken
4:Thread starten -> Checkbox klicken -> Exit klicken
5:Thread starten -> Checkbox klicken -> Checkboxen klicken
6:Thread starten -> Stopp klicken -> Exit klicken

1: Thread wird gestartet und VB schmiert ab
2: Thread wird gestartet, danach gestoppt
3: Thread wird gestartet und danach angehalten
4: Thread wird gestartet, danach angehalten, danach schmiert vb ab
5: Thread wird gestartet, danach angehalten, danach fortgesetzt
6: Thread wird gestartet, Thread wird gestoppt, VB wird beendet. VB schmiert NICHT ab!

Ich hoffe ich konnte es dir jetzt ein wenig naeher bringen :wink:
Achso. TerminateThread sollte man tünlichst vermeiden, alldiweil alle Resourcen die der Thread belegt hat, werden dann nicht wieder freigegeben. Das macht man nur wenn sich ein Thread aufgehangen hat und selbst dann musst du den Speicher manuell wieder aufraeumen :frowning:

MfG Alex

1 Like

Hi Alex,

jaaaaa, jetzt ist das eine runde Sache!
Da soll noch mal Jemand behaupten, Multithreading mit VB6 wäre ein Problem. :smile:

Danke!

Gruß, Rainer

Hi Alex,

hmmm, der neue Thread läuft zwar asynchron, aber wenn er sich aufhängt, soll er ja ‚von außen‘ gestoppt und neu gestartet werden. Das geht so nicht. Du übergibst einen Wert an ein Flag und davon abhängig beendet sich der Thread selbst. :frowning: So ganz ist das Ziel wohl doch noch nicht erreicht.

Gruß, Rainer

Hallo Rainer,

ich habe den ganzen Thread nicht intensiv verfolgt. So wie ich es verstanden habe, hatte er eine Lösung gefunden. Dies bestand daraus irgendwas mit Sendmessage zu senden und dann auf Antwort warten. Je nachdem wusste er dann ob das prog sich aufhaengt oder nicht und konnte dann agieren.
Sein Problem war nun aber das wenn er dies realisierte das dann auch sein VB Program solange gewartet hatte.
Dies kannst du mit einen Thread umgehen, da ja das VB Program weiter abgearbeitet wird. Alternativ, könnte er auch noch die WaitForSingle API in Betracht ziehen. So kann er noch ein maximales Limit setzen, also wielange der Thread max. warten soll, bevor er sich beendet.

Meine Idee mit dem Flag war nur gedacht um zu umgehen das VB abschmiert, während er noch im Thread haengt.

MfG Alex

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

geht leider doch nicht.
Hi Alex,

das klappt leider nicht. Der Aufruf von CreateThread funktioniert nur in der Entwicklungsumgebung, sobald das Programm kompiliert wird, stürzt es ab, sobald der Thread aktiviert wird. :frowning:

Gruß, Rainer