AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Externes von mir gestartes Programm beenden? Hilfe!
Thema durchsuchen
Ansicht
Themen-Optionen

Externes von mir gestartes Programm beenden? Hilfe!

Offene Frage von "firefighter"
Ein Thema von firefighter · begonnen am 8. Jan 2004 · letzter Beitrag vom 9. Jan 2004
Antwort Antwort
Seite 1 von 2  1 2      
firefighter

Registriert seit: 8. Jan 2004
10 Beiträge
 
#1

Externes von mir gestartes Programm beenden? Hilfe!

  Alt 8. Jan 2004, 11:49
Erstmal hallo,

bevor Ihr mich steinigt - ich habe bereits gesucht und viele Informationen gefunden, aber leider nicht die passende. Ich bin auch Anfänger auf dem Gebiet der Windows API also seit bitte lieb zu mir

Folgendes:

Ich versuche ein zeitgesteuertes Programm zu schreiben, welches alle xx Minuten eine Website öffnet und nach xx minuten wieder schliesst - quasi cronjob ersatz.

Um das Programm zu starten nutze ich CreateProcess, wobei ich TProcessInformation globalisiert habe, um in einem zweiten Timer über TerminateProcess wieder zu schliessen. Funktioniert sehr gut, aber ich wollte nach weiteren Suchen und Lesen hier auf wm_close umstellen und damit auf den TerminateProcess verzichten.

Das Programm ist wie ich das löse? Die Crons werden über den IE gesteuert, womit das suchen per findwindow ausfällt. Ich kenne den Text nicht und er könnte sich auch ändern. Ich habe z.z. nur den hProcess der für den TerminateProcess auslangt. Das Programm wird für die Zukunft auch durch andere Scriptanwendungen als der IE als Webseitenaufruf dienen.

Zusammengefasst: Wie schliesse ich per wm_close (bitte in sourcecode - bin n00b) ein Programm bei dem ich nur den pid von createprocess habe?

Ich hoffe mir kann jemand schnell helfen!

-firefighter
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#2

Re: Externes von mir gestartes Programm beenden? Hilfe!

  Alt 8. Jan 2004, 12:30
Hallo firefighter,

ein herzliches Wilkommen zur Delphi-PRAXiS!

Wenn ich Dich richtig verstanden habe, möchtest Du die Handles aller Top-Level-Fenster zu einem bestimmten Process ermitteln.
Leider ist mir keine direkte API-Funktion hierzu bekannt, allerdings kannst Du mit EnumWindows über alle Top-Level-Fenster iterieren und dank GetWindowThreadProcessId auch die jeweilige ProcessID ermitteln. Weil die CallBack-Funktion EnumWindowsProc einen frei verwendbaren Paramter entgegennehmen kann, bietet es sich an, hier die ProcessID zu übergeben, so dass direkt in diese CallBack-Funktion an alle diejenigen Fenster die Botschaft WM_CLOSE geschickt werden könnte, deren ProcessID mit der übergebenen übereinstimmen.

Das Prinzip von CallBack-Funktionen und API-Calls iA ist wiederkehrend, so dass es wert ist, sich mit diesen Themen genauer zu beschäftigen. Die notwendigen Infos solltest Du in der OH, bzw dem PSDK bekommen.
Noch ein Hinweis: Der C Datentyp Bool sollte nach LongBool "übersetzt" werden und die Aufrufkonvention von EnumWindowsProc ist stdcall, so dass die Deklaration der CallBack-Funktion in etwas so aussehen könnte
function MyEnumWindowsProc(AHandle: HWND; APRocessID: Cardinal): LongBool; stdcall;
gruß, choose
  Mit Zitat antworten Zitat
firefighter

Registriert seit: 8. Jan 2004
10 Beiträge
 
#3

Re: Externes von mir gestartes Programm beenden? Hilfe!

  Alt 8. Jan 2004, 12:46
Zitat von choose:
Hallo firefighter,

ein herzliches Wilkommen zur Delphi-PRAXiS!

Wenn ich Dich richtig verstanden habe, möchtest Du die Handles aller Top-Level-Fenster zu einem bestimmten Process ermitteln.
Leider ist mir keine direkte API-Funktion hierzu bekannt, allerdings kannst Du mit EnumWindows über alle Top-Level-Fenster iterieren und dank GetWindowThreadProcessId auch die jeweilige ProcessID ermitteln. Weil die CallBack-Funktion EnumWindowsProc einen frei verwendbaren Paramter entgegennehmen kann, bietet es sich an, hier die ProcessID zu übergeben, so dass direkt in diese CallBack-Funktion an alle diejenigen Fenster die Botschaft WM_CLOSE geschickt werden könnte, deren ProcessID mit der übergebenen übereinstimmen.

Das Prinzip von CallBack-Funktionen und API-Calls iA ist wiederkehrend, so dass es wert ist, sich mit diesen Themen genauer zu beschäftigen. Die notwendigen Infos solltest Du in der OH, bzw dem PSDK bekommen.
Noch ein Hinweis: Der C Datentyp Bool sollte nach LongBool "übersetzt" werden und die Aufrufkonvention von EnumWindowsProc ist stdcall, so dass die Deklaration der CallBack-Funktion in etwas so aussehen könnte
function MyEnumWindowsProc(AHandle: HWND; APRocessID: Cardinal): LongBool; stdcall;
Danke für herzlichen Begrüssungstext
Irgendwie muss ich über die pid einen handle auf das fenster z.b. vom IE bekommen. Du schreibst, dass Dir keine direkte API-Funktion dazu bekannt ist, aber über Umwege dennoch das Ziel erreicht werden kann. Was Du im Anschluss geschrieben hast verwirrte mich leider nur zum grössten Teil.

Meist du man schreibt eine Schleife die alle handels durchgeht und davon die pid ausgibt, welche mit meiner vorhanden pid verglichen wird? Falls ja, habe ich den Inhalt verstanden, stehe aber dank meines Anfängerwissens vor einem grossen Problem - der Umsetzung.

Wie schwer wäre eine function, welche als Paramter die PID und als Rückgabewert den handle beinhaltet? Falls dies nicht sonderlich schwer wäre, würde ich mich riesig freue diese zu bekommen.

firefighter

PS: Danke schonmal für die Antwort
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#4

Re: Externes von mir gestartes Programm beenden? Hilfe!

  Alt 8. Jan 2004, 13:03
Das Problem besteht darin, dass es mehrere Top-Level-Fenster zu einem Prozess geben kann. Ein "leeres" Delphi-Programm hat bspw ein Fenster der Klasse TApplication und eins der Klasse TForm1. Es ist also unbedingt soetwas ähnliches wie eine "Schleife" notwendig, um das Problem zu lösen.

Wenn Du einmal in der Delphi Online-Hilfe (OH) den Begriff EnumWindows nachschlägst, sollte die Hilfedatei der Windows-API (Bestandteil des PSDK) gezeigt werden und es ist zu erkennen, dass diese Funktion zwei Parameter erwartet, von der der erste eine sog. CallBack-Funktion ist:
Zitat:
Points to an application-defined callback function. For more information, see the EnumWindowsProc callback function.
Eine CallBack-Funktion ist soetwas ähnliches wie eine Schleife (genauer: Bei Google sucheninternal iterator pattern) und ist in anderen Programmiersprachen verbreiteter. Beim Einsatz von CallBack-Funktionen wird der Gedanke des Zuständigkeitsprinzips verfolgt: Der Iterator (hier: EnumWindows) "weiß", wie man an die Elemente "herankommt" (hier: Die Handles der Top-Level-Fenster) und der Client (hier: Dein Programm, genauer die CallBack-Funktion deines Programms) weiß, was mit diesen Elementen getan werden soll. Auf diese Weise lässt sich EnumWindows für viele Zwecke Einsetzen, weil sie von der tatsächlichen Logik entkoppelt ist, ohne dass der Client eigene Schleife programmieren muss (zB auf der Basis von GetWindow).

Dieser Absatz, die Hilfetexte zu EnumWindowsProc sowie das vorherige Posting mit dem Gedanken, welche Logik nun in der CallBack-Funktion enthalten sein könnte, helfen Dir vielleicht schon weiter...
gruß, choose
  Mit Zitat antworten Zitat
firefighter

Registriert seit: 8. Jan 2004
10 Beiträge
 
#5

Re: Externes von mir gestartes Programm beenden? Hilfe!

  Alt 8. Jan 2004, 14:41
Ein Freund von mir hat dieses Problem mit C++ gelöst. Dies Lösung will ich Euch nicht vorenthalten. @choose: Wie Du siehst, scheint er es so gemacht zu haben wie Deine Idee war Jetzt muss diese Lösung nur noch auf Delphi transponiert werden

Delphi-Quellcode:
static BOOL CALLBACK CloseProcWndCB(HWND hWnd, LPARAM lParam)

DWORD dwPID = 0;
::GetWindowThreadProcessId(hWnd, &dwPID);
if (dwPID == (DWORD)lParam)
{
::PostMessage(hWnd, WM_CLOSE, NULL, NULL);
}

return TRUE;
}

void CloseProcessWindows(DWORD dwPID)
{
EnumChildWindows(::GetDesktopWindow(), CloseProcWndCB, (LPARAM)dwPID);
}
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#6

Re: Externes von mir gestartes Programm beenden? Hilfe!

  Alt 8. Jan 2004, 17:12
Ja, genau so geht's
gruß, choose
  Mit Zitat antworten Zitat
Benutzerbild von SleepyMaster
SleepyMaster

Registriert seit: 18. Mai 2003
634 Beiträge
 
#7

Re: Externes von mir gestartes Programm beenden? Hilfe!

  Alt 8. Jan 2004, 17:51
Ich würde es so machen (aber wahrscheinlich nur weil ich es anders nicht kann ):

Delphi-Quellcode:
function RunProcess(FileName: string; ShowCmd: DWORD; wait: Boolean; ProcID: PDWORD): Longword;
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin
  FillChar(StartupInfo, SizeOf(StartupInfo), #0);
  StartupInfo.cb := SizeOf(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
  StartupInfo.wShowWindow := ShowCmd;
  if not CreateProcess(nil,
    @Filename[1],
    nil,
    nil,
    False,
    CREATE_NEW_CONSOLE or
    NORMAL_PRIORITY_CLASS,
    nil,
    nil,
    StartupInfo,
    ProcessInfo)
    then
      Result := WAIT_FAILED
  else
  begin
    if wait = FALSE then
    begin
      if ProcID <> nil then ProcID^ := ProcessInfo.dwProcessId;
      exit;
    end;
    WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
    GetExitCodeProcess(ProcessInfo.hProcess, Result);
  end;
  if ProcessInfo.hProcess <> 0 then
    CloseHandle(ProcessInfo.hProcess);
  if ProcessInfo.hThread <> 0 then
    CloseHandle(ProcessInfo.hThread);
end;

function KillProcess(PID: DWord): Bool;
var
  hProcess: THandle;
begin
  hProcess := OpenProcess(PROCESS_TERMINATE, False, PID);
  Result := TerminateProcess(hProcess, 0);
end;

procedure TForm1.Button1Click(Sender: TObject); //starten
begin
  RunProcess(Paramstr(0), SW_SHOW, FALSE, @ProcID);
end;

procedure TForm1.Button2Click(Sender: TObject); //beenden
begin
KillProcess(ProcID);
end;
P.S.: Meine Meinung zu C/C++: siehe Unten
  Mit Zitat antworten Zitat
Benutzerbild von SleepyMaster
SleepyMaster

Registriert seit: 18. Mai 2003
634 Beiträge
 
#8

Re: Externes von mir gestartes Programm beenden? Hilfe!

  Alt 8. Jan 2004, 17:54
<---- Kann ned lesen

Zitat:
Funktioniert sehr gut, aber ich wollte nach weiteren Suchen und Lesen hier auf wm_close umstellen und damit auf den TerminateProcess verzichten.
  Mit Zitat antworten Zitat
firefighter

Registriert seit: 8. Jan 2004
10 Beiträge
 
#9

Re: Externes von mir gestartes Programm beenden? Hilfe!

  Alt 9. Jan 2004, 09:12
Zitat von choose:
Ja, genau so geht's
ok, dann schau mal bitte was hier mein Fehler ist:

Delphi-Quellcode:
Function CloseProcWndCB(hWnd :HWND; param :lparam): Boolean; stdcall;
Begin
 GetWindowThreadProcessId(hWnd, @dwPID);
 if (dwPID = param) Then
 begin
  PostMessage(hWnd, WM_CLOSE, NULL, NULL);
 end;
 CloseProcWndCB := true;
End;

Procedure CloseProcessWindows(dwPID :dword);
Begin
 EnumWindows(@CloseProcWndCB, dwPID);
End;
Über CloseProcessWindows wird nur die PID übergeben und sollte das Programm dann schliessen, aber es passiert gar nichts. Ich hab sicher was falsch gemacht. Nur was?
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#10

Re: Externes von mir gestartes Programm beenden? Hilfe!

  Alt 9. Jan 2004, 09:28
Zunächst einmal solltest Du Bool nicht mit Boolean sondern mit LongBool übersetzen, dann reicht es vollkommen aus, für das Ergebnis von GetWindowThreadProcessId eine lokale Variable (wo und wie ist dwPID denn deklariert?) und die delphi-typische Version ohne Pointer zu verwenden.

Ansonsten kann ich keinen Fehler entdecken, meine getestete Version sieht annähernd genauso aus und funktioniert. Vielleicht übergibst Du an CloseProcessWindows keine ProcessID sondern ein Handle auf den Prozess?
Überprüfen kannst Du das ganze mit einem Aufgruf der Form
CloseProcessWindows(GetCurrentProcessID); mit dem eigenen Programm.
gruß, choose
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:41 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz