Ich starte ein Shell Programm mittels
S := LinuxSamplerPath+'\LinuxSampler.exe';
S := '"'+S+'"';
X := ShellExecute(Handle, 'open', PChar(S), NIL,'', SW_SHOWNORMAL);
if x <33 then ews('Not valid '+S);
Klappt prima.
Aber, wie kann ich dieses Programm wieder schlie�en?
Ich habe schon sowas versucht:
Handle:=FindWindow(Nil,PChar(s));
if (Handle>0) then
begin
Sendmessage(Handle,WM_Close ,0,0);
end;
Danke.
Mit freundlichen Gr��en
Norbert
> Handle:=FindWindow(Nil,PChar(s));
An dieser Stelle ist es wichtig zu wissen welcher Name das Fenster der
zu beendenen Anwendung hat (Text im Caption-Feld). Zus�tzlich w�re auch
der Klassenname brauchbar.
Wenn Du ein neues Anwendungsprojekt in Delphi erstellst, wird der Name
der Form mit Form1 und der Klassenname mit TForm1 vorbelegt. Ein solches
Fenster w�rdest Du folgenderma�en suchen:
Handle:=FindWindow('TForm1','Form1');
Der Nachteil ist, da� ja bereits mehrere Programme von Dir auf einem PC
laufen k�nnten, die die selben Namen haben. Dann wird irgendeins von
diesen Fenstern als erstes gefunden.
Soll der Klassenname beibehalten werden, dann brauchst Du ein
eindeutiges Caption.
Handle:=FindWindow(nil,'Mein eigenes Programm'); //geht dann auch.
Besser w�re Klassenname und Fenstername individuell zu w�hlen.
Handle:=FindWindow('TMyForm','MyForm'); //oder wie auch immer
Nur wenn Du dieses Programm mehrmals startest, hast Du das gleiche
Problem wie oben.
Das ganze l�sst sich auch auf Applicationebene durchf�hren.
Handle:=FindWindow('TApplication','MeinProject');
Auch hier ist es wichtig, dass der Name eindeutig ist.
> if (Handle>0) then
> begin
> Sendmessage(Handle,WM_Close ,0,0);
> end;
Besser w�re (meine Meinung): Postmessge(Handle,WM_Close ,0,0);
Mfg
Georg H�bner
>Ich starte ein Shell Programm mittels
Leider habe ich das wohl nicht richtig klargemacht:
Shellprogramm = Programm welches in der Shell l�uft, also ein
Programm ohne GUI
Ohne Fensterhandle l�uft da nichts.
Ich habe es auch so versucht:
function Exec(FileName: String; Visibility: Integer ): DWORD;
var { V1 by Pat Ritchey, V2 by P.Below }
zAppName: Array[0..512] of char;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
begin { WinExecAndWait32V2 }
StrPCopy(zAppName, FileName);
FillChar(StartupInfo, Sizeof(StartupInfo), #0);
StartupInfo.cb := Sizeof(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := Visibility;
if not CreateProcess(nil,
zAppName, { pointer to command line string }
nil, { pointer to process security attributes }
nil, { pointer to thread security attributes }
false, { handle inheritance flag }
CREATE_NEW_CONSOLE or { creation flags }
NORMAL_PRIORITY_CLASS,
nil, { pointer to new environment block }
nil, { pointer to current directory name }
StartupInfo, { pointer to STARTUPINFO }
ProcessInfo) { pointer to PROCESS_INF }
then Result := DWORD(-1) { failed, GetLastError has error code }
else
begin
MyHandle := ProcessInfo.hprocess;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
GetExitCodeProcess(ProcessInfo.hProcess, Result);
CloseHandle(ProcessInfo.hProcess );
CloseHandle(ProcessInfo.hThread );
end; { Else }
end; { WinExecAndWait32V2 }
wobei MyHandle := ProcessInfo.hprocess; das Handle sein soll.
Trotzdem wird die Shell nicht beendet mittels Sendmessage(MyHandle,WM_Close
,0,0);
Ich habe keine Idee mehr, was ich da wohl falsch mache.
> Ich starte ein Shell Programm mittels
>
> S := LinuxSamplerPath+'\LinuxSampler.exe';
> Klappt prima.
> Aber, wie kann ich dieses Programm wieder schlie�en?
>
> Ich habe schon sowas versucht:
>
> Handle:=FindWindow(Nil,PChar(s));
> if (Handle>0) then
> begin
> Sendmessage(Handle,WM_Close ,0,0);
> end;
Ich versuche auch gerade �ber Fensterhandles und diverses (auch
h�ngende) Programme zu schlie�en und bin auf das Windows-Bordmittel
"Taskkill" gesto�en:
Winexec('taskkill /F /IM name.exe',SW_SHOWNORMAL);
Damit bekomme ich (auf brutalste Weise) jede Anwendung in die Knie, von
der ich den Namen im TaskManager kenne, egal, ob sie regul�r laufen oder
sich aufgeh�ngt haben.
WM_CLOSE zu senden ist die sanftere Methode, aber dazu brauchst du den
Namen des Hauptfensters, und den zu besorgen, ist nicht einfach. In
einem fr�heren Thread schrieb ich:
> PostMessage(GetHandleFromExeName('Programm1.exe'),WM_CLOSE,0,0);
> wobei GetHandleFromExeName das FensterHandle liefert.
> Ein leeres Projekt (Programm1.exe) schlie�t sich auch brav sofort.
> Wenn ich aber z.B. einen Timer ins Formular einf�ge, muss ich schon
> zweimal WM_CLOSE schicken, bis sich das Programm beendet. Wo landet
> das erste WM_CLOSE?
Ich mach jetzt auf "Rocky" und w�rge die Anwendungen ab wie oben
beschrieben.
Alfred.
> Ich habe keine Idee mehr, was ich da wohl falsch mache.
Setz mal "cmd /c " vor den Dateinamen. Dann wird die Shell
beendet, wenn das Programm fertig ist.
MfG
Gerd
> Ich versuche auch gerade �ber Fensterhandles und diverses (auch h�ngende)
> Programme zu schlie�en und bin auf das Windows-Bordmittel "Taskkill"
> gesto�en:
> Winexec('taskkill /F /IM name.exe',SW_SHOWNORMAL);
Versucht. Leider kommt dann die Fehlermeldung:
Die Anwendung konnte nicht gestartet werden, weil framedyn.dll nicht
gefunden wurde.
Gegoogelt und dann erst mal das framedyn.dll behoben.
dann nochmal Winexec('taskkill /F /IM name.exe',SW_SHOWNORMAL);
Leider wird die Anwendung dadurch nicht beendet.
Ich habe das genauso eingegeben, wie mir der Taskmanager das anzeigt.
Dann habe ich das in der DOS Shell eingegeben.
Fehlermeldung: Ung�ltiger NameSpace
versuch mal folgendes:
ShellExecute(Handle,'open','C\<Pfadangabe>\TestKonsole.exe',nil,nil,SW_SHOWNORMAL);
dann:
FMyHandle:=FindWindowEx(0,0,nil,'C:\<Pfadangabe>\TestKonsole.exe');
und schliessen:
PostMessage(FMyHandle,WM_CLOSE,0,0);
Die Konsolen-Anwendung sieht so aus:
program TestKonsole;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
HlpStr: String;
begin
HlpStr:='Hallo Welt!';
Writeln(HlpStr);
Readln;
end.
Hat bei mir funktioniert :-)
Mfg
Georg H�bner
>> versuch mal folgendes:
>>
ShellExecute(Handle,'open','C\<Pfadangabe>>\TestKonsole.exe',nil,nil,SW_SHOWNORMAL);
>> dann:
>> FMyHandle:=FindWindowEx(0,0,nil,'C:\<Pfadangabe>\TestKonsole.exe');
>
>FMyHandle ist 0
>Da kann ich machen was ich will..............
>
>Mit freundlichen Gr��en
>Norbert
�ffne doch mal den Task-Manager > Anwendungen
Da m�sste nach ShellExecute dann
C:\Dokumente und Einstellungen\All Users\Test\TestKonsole.exe Wird
ausgef�hrt
stehen. (Pfadangaben aus meinem Beispiel)
Wenn nicht, dann ist TestKonsole.exe nicht gestartet worden oder sie ist
bereits wieder beendet.
Hier der komplette Quellcode zum Testen:
//***************
//Hauptprogramm
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
Dialogs, StdCtrls, ShellApi;
type
TTestForm1 = class(TForm)
Label1: TLabel;
Shellstart: TButton;
Finden: TButton;
Schliessen: TButton;
procedure FindenClick(Sender: TObject);
procedure SchliessenClick(Sender: TObject);
procedure ShellstartClick(Sender: TObject);
private
{ Private-Deklarationen }
FMyHandle: THandle;
public
{ Public-Deklarationen }
end;
var
TestForm1: TTestForm1;
implementation
{$R *.dfm}
procedure TTestForm1.ShellstartClick(Sender: TObject);
begin
try
ShellExecute(Handle,'open',
'C:\Dokumente und Einstellungen\All Users\Test\TestKonsole.exe',
nil,nil,SW_SHOWNORMAL);
except
end;
end;
procedure TTestForm1.FindenClick(Sender: TObject);
begin
try
FMyHandle:=FindWindowEx(0,0,nil,
'C:\Dokumente und Einstellungen\All Users\Test\TestKonsole.exe');
except
end;
Label1.Caption:=IntToHex(FMyHandle,8);
end;
procedure TTestForm1.SchliessenClick(Sender: TObject);
begin
try
PostMessage(FMyHandle,WM_CLOSE,0,0);
except
end;
end;
end.
//***************
//Testkonsole.exe
program TestKonsole;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
HlpStr: String;
begin
HlpStr:='Hallo Welt!';
Writeln(HlpStr);
Readln;
end.
Das funktioniert auf meinem Rechner tadellos.
WinXP SP3, alle aktuellen Updates
Delphi7 Pro
Mfg
Georg H�bner
> �ffne doch mal den Task-Manager > Anwendungen
> Da m�sste nach ShellExecute dann
> C:\Dokumente und Einstellungen\All Users\Test\TestKonsole.exe Wird
> ausgef�hrt
> stehen. (Pfadangaben aus meinem Beispiel)
Ja, steht es.
Aber nach dem Shellexecute ist MyHandle:=FindWindowEx = 0
(Auch nach sleep(5000))
Dann versuch es mal mit einem Thread.
Der einfachheithalber kopiere ich nochmal den gesamten Quell-Code:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
Dialogs, StdCtrls, ShellApi;
const
WM_SETSHELLWINHANDLE = WM_User + 800;
type
TMyThread = class(TThread)
private
{ Private-Deklarationen }
HlpHandle: THandle;
protected
procedure Execute; override;
end;
type
TTestForm1 = class(TForm)
Label1: TLabel;
Shellstart: TButton;
Finden: TButton;
Schliessen: TButton;
procedure FindenClick(Sender: TObject);
procedure SchliessenClick(Sender: TObject);
procedure ShellstartClick(Sender: TObject);
private
{ Private-Deklarationen }
FMyHandle: THandle;
procedure SetShellWinHandle(var Message: TMessage); message
WM_SETSHELLWINHANDLE;
public
{ Public-Deklarationen }
end;
var
MyThread: TMyThread;
TestForm1: TTestForm1;
implementation
{$R *.dfm}
procedure TMyThread.Execute;
begin
while not Terminated do
begin
try
HlpHandle:=FindWindowEx(0,0,nil,
'C:\Dokumente und Einstellungen\All Users\Test\TestKonsole.exe');
except
end;
if HlpHandle <> 0 then
begin
PostMessage(TestForm1.Handle,WM_SETSHELLWINHANDLE,HlpHandle,0);
Terminate;
end;
end;
end;
procedure TTestForm1.ShellstartClick(Sender: TObject);
begin
try
ShellExecute(Handle,'open',
'C:\Dokumente und Einstellungen\All Users\Test\TestKonsole.exe',
nil,nil,SW_SHOWNORMAL);
except
end;
MyThread:=TMyThread.Create(False);
MyThread.FreeOnTerminate:=True;
end;
procedure TTestForm1.FindenClick(Sender: TObject);
begin
try
FMyHandle:=FindWindowEx(0,0,nil,
'C:\Dokumente und Einstellungen\All Users\Test\TestKonsole.exe');
except
end;
Label1.Caption:=IntToHex(FMyHandle,8);
end;
procedure TTestForm1.SchliessenClick(Sender: TObject);
begin
try
PostMessage(FMyHandle,WM_CLOSE,0,0);
except
end;
end;
procedure TTestForm1.SetShellWinHandle(var Message: TMessage);
begin
FMyHandle:=Message.WParam;
Label1.Caption:=IntToHex(FMyHandle,8);
end;
end.
Mfg
Georg H�bner
> FMyHandle:=FindWindowEx(0,0,nil,'C:\<Pfadangabe>\TestKonsole.exe');
>
> und schliessen:
>
> PostMessage(FMyHandle,WM_CLOSE,0,0);
Aehem, die Win32-Hilfe sagt:
HWND FindWindowEx(
HWND hwndParent, // handle to parent window
HWND hwndChildAfter, // handle to a child window
LPCTSTR lpszClass, // pointer to class name
LPCTSTR lpszWindow // pointer to window name
);
Das hat mit dem, was Du vorschl�gts aber auch gar nix zu tun.
Alfred.
> Dann versuch es mal mit einem Thread.
> Der einfachheithalber kopiere ich nochmal den gesamten Quell-Code:
Vielen Dank f�r Deine M�he.
Ich habe es zuerst nat�rlich mit Deiner Consolenanwendung getestet. Das
l�uft.
Aber mit der ANwendung, die ich starten muss, geht nix. (Fast nix)
Ich sehe zwar nun ein anderes Handle.
Ich sehe auch das Handle, wenn ich FindHandle bet�tige. Alles ok.
Aber auf WM_Quit reagiert das Teil nicht.
Ich verstehe das nicht.
Auf Ctrl C (h�ndisch eingegeben) funktioniert das.
Kann man vieleicht ^C an das Handle schicken?
Nur mal so als Idee.
Und weiter steht da:
Parameters
hwndParent
Identifies the parent window whose child windows are to be searched.
If hwndParent is NULL, the function uses the desktop window as the
parent window. The function searches among windows that are child
windows of the desktop.
hwndChildAfter
Identifies a child window. The search begins with the next child window
in the Z order. hwndChildAfter must be a direct child window of
hwndParent, not just a descendant window.
If hwndChildAfter is NULL, the search begins with the first child window
of hwndParent.
- hier der wichtigste Satz:
Note that if both hwndParent and hwndChildAfter are NULL, the function
searches all top-level windows.
Ich habe hier Beispiel-Code gepostet, der einwandfrei funktioniert!
Als zus�tzliches Hilfsmittel, um festzustellen ob das ermittelte Handle
richtig ist und wie die Zusammenh�nge sind, habe ich Spy++ benutzt.
Dieses Tool ist Bestandteil von Microsoft Visual Studio 6.0.
Zugegeben, das ermittelte Handle ist nicht das von TestKonsole.exe,
sondern das des Konsolen-Fensters.
In Spy++ wird dieses Konsolen-Handle, der komplete Pfad mit der
EXE-Datei und der Konsolen-Klassenname (ConsoleWindowClass) angezeigt.
Also, was ist daran jetzt falsch diesen von mir vorgeschlagen Weg zu
gehen? Es funktioniert und erf�llt, soweit ich das Problem von Norbert
verstanden habe, auch seine Anforderungen.
Wenn man das ganze anders haben will, mu� man die ProzessID (PID) von
TestKonsole.exe ermitteln und kann dann z.B. mit Taskkill /PID xxxx den
Prozess abschiessen. Leider habe ich noch keinen Weg gefunden die PID
direkt zu ermitteln. :-(
Ich bin deshalb auch f�r jeden Hinweis dankbar.
Mfg
Georg H�bner
> Vielen Dank f�r Deine M�he.
> Ich habe es zuerst nat�rlich mit Deiner Consolenanwendung getestet. Das
> l�uft.
> Aber mit der ANwendung, die ich starten muss, geht nix. (Fast nix)
>
> Ich sehe zwar nun ein anderes Handle.
> Ich sehe auch das Handle, wenn ich FindHandle bet�tige. Alles ok.
> Aber auf WM_Quit reagiert das Teil nicht.
Nicht WM_Quit sondern WM_Close!
Die Botschaft wird an das Konsolen-Fenster geschickt und das m�sste
eigentlich mit WM_Close schliessen. :-|
Mfg
Georg H�bner
> Nicht WM_Quit sondern WM_Close!
>
> Die Botschaft wird an das Konsolen-Fenster geschickt und das m�sste
> eigentlich mit WM_Close schliessen. :-|
Hab' ich alles versucht. M��te eigentlich ist gut.
Tut es aber nicht :)
Wenn Du Deine Anwendug �ber ShellExecute startest, ist doch auch ein
Dos-Fenster (Konsolen-Fenster) sichtbar, oder?
Ich gehe mal davon aus.
L�sst sich dieses Fenster �ber das eigene Icon-Menue oder �ber den
Schliessen-Button (rechts oben im Fenster) problemlos schliessen?
Was genau macht Dein Programm?
Mfg
Georg H�bner
> Dos-Fenster (Konsolen-Fenster) sichtbar, oder?
> Ich gehe mal davon aus.
Ja.
> L�sst sich dieses Fenster �ber das eigene Icon-Menue oder �ber den
> Schliessen-Button (rechts oben im Fenster) problemlos schliessen?
Ja. Und auch mittels Ctrl C
> Was genau macht Dein Programm?
Es ist ein Consolen Programm, dem man �ber TCPIP Befehle schickt.
> - hier der wichtigste Satz:
> Note that if both hwndParent and hwndChildAfter are NULL, the function
> searches all top-level windows.
>
> Ich habe hier Beispiel-Code gepostet, der einwandfrei funktioniert!
> Als zus�tzliches Hilfsmittel, um festzustellen ob das ermittelte Handle
> richtig ist und wie die Zusammenh�nge sind, habe ich Spy++ benutzt.
> Dieses Tool ist Bestandteil von Microsoft Visual Studio 6.0.
> Zugegeben, das ermittelte Handle ist nicht das von TestKonsole.exe,
> sondern das des Konsolen-Fensters.
> In Spy++ wird dieses Konsolen-Handle, der komplete Pfad mit der
> EXE-Datei und der Konsolen-Klassenname (ConsoleWindowClass) angezeigt.
>
> Also, was ist daran jetzt falsch diesen von mir vorgeschlagen Weg zu
> gehen? Es funktioniert und erf�llt, soweit ich das Problem von Norbert
> verstanden habe, auch seine Anforderungen.
Meiner Ansicht nach ist es falsch, mit FindWindow/Ex nach Pfaden und
ExeNamen zu suchen, in deinem Beispiel m�sste der Fenstertext (die
Caption, wie sie bei der Fensterregistrierung war) stehen.
Es mag Zufall sein, dass der Fenstertext, den du gefunden hast mit dem
Exename irgenwie korrespnodiert, ich glaube aber nicht, dass
FindWindowEx mit dem Exenamen als Suchparameter *Sicher* funktioniert.
> Wenn man das ganze anders haben will, mu� man die ProzessID (PID) von
> TestKonsole.exe ermitteln und kann dann z.B. mit Taskkill /PID xxxx den
> Prozess abschiessen. Leider habe ich noch keinen Weg gefunden die PID
> direkt zu ermitteln. :-(
> Ich bin deshalb auch f�r jeden Hinweis dankbar.
TaskKill funktioniert ja auch mit dem Exenamen (/IM). Ich meine aber,
die PID aus dem ExeNamen bestimmen zu k�nnen, habe den Code dazu nicht
hier. Ich schaue morgen im B�ro nach, wenn es dich interessiert.
Gru�, Alfred.
> Meiner Ansicht nach ist es falsch, mit FindWindow/Ex nach Pfaden und
> ExeNamen zu suchen, in deinem Beispiel m�sste der Fenstertext (die
> Caption, wie sie bei der Fensterregistrierung war) stehen.
>
> Es mag Zufall sein, dass der Fenstertext, den du gefunden hast mit dem
> Exename irgenwie korrespnodiert, ich glaube aber nicht, dass
> FindWindowEx mit dem Exenamen als Suchparameter *Sicher* funktioniert.
Da ist absolut nichts falsch. Die Pfad + EXE-Datei Angabe beim Aufruf
von FindWindowEx ist der Caption-Text, der im Dos-Fenster steht.
Es gibt aber zwei Varianten.
Wenn man aus einem eigenen Programm heraus mit
ShellExecute(Handle,'open','C:\Dokumente und Einstellungen\All
Users\Test\TestKonsole.exe',
das Konsolenprogramm aufruft, steht exakt dies
C:\Dokumente und Einstellungen\All Users\Test\TestKonsole.exe
im Caption.
Wenn man aber in Windows �ber Start > Ausf�hren > cmd.exe startet, dann
in der Dos-Box sich das Verzeichnis einstellt (cd C:\Dokumente und
Einstellungen\All Users\Test) und danach TestKonsole.exe aufruft, dann
steht im Caption folgendes:
C:\WINDOWS\System32\cd.exe - testkonsole.exe
In diesem Fall findet man das Dos-Femster aus seinem eigenen Programm
heraus nat�rlich nicht.
> TaskKill funktioniert ja auch mit dem Exenamen (/IM). Ich meine aber,
Das ist ja noch besser als nach der PID suchen. Ich hatte mir die
TasKill-Optionen nicht so genau angesehen und dies leider �bersehen. :-(
Ich habs gleich mal ausprobiert:
ShellExecute(Handle,'open','taskkill.exe',' /IM TestKonsole.exe
/F',nil,SW_SHOWNORMAL)
Das funktioniert! :-)
Ich w�rde diese Methode bevorzugen. Besser als nach dem Handle zu suchen.
> die PID aus dem ExeNamen bestimmen zu k�nnen, habe den Code dazu nicht
> hier. Ich schaue morgen im B�ro nach, wenn es dich interessiert.
Das w�rde mich aber trotzdem interessieren.
Mfg
Georg H�bner
> Wenn man aus einem eigenen Programm heraus mit
>
> ShellExecute(Handle,'open','C:\Dokumente und Einstellungen\All
> Users\Test\TestKonsole.exe',
>
> das Konsolenprogramm aufruft, steht exakt dies
>
> C:\Dokumente und Einstellungen\All Users\Test\TestKonsole.exe
>
> im Caption.
Ok, das habe ich �bersehen.
>> die PID aus dem ExeNamen bestimmen zu k�nnen, habe den Code dazu nicht
>> hier. Ich schaue morgen im B�ro nach, wenn es dich interessiert.
>
> Das w�rde mich aber trotzdem interessieren.
Ich schau mal danach.
Alfred
> Dann habe ich das in der DOS Shell eingegeben.
> Fehlermeldung: Ung�ltiger NameSpace
Ich bin mir nicht sicher, aber vielleicht hilft Dir das hier zum Thema
NameSpace weiter:
http://support.microsoft.com/kb/281888/de
Ich kenne mich mit diesem Thema leider nicht aus. :-)
Deshalb bitte nicht b�se sein, wenn es nicht genutzt hat.
Mfg
Georg H�bner
>> Was genau macht Dein Programm?
>
> http://www.linuxsampler.org/
>
> Es ist ein Consolen Programm, dem man �ber TCPIP Befehle schickt.
Tja. Das ist ja schon ein m�chtiges Projekt. Leider kann man aufgrund
der Informationen auf der Web-Seite nicht erkennen wie tief der
Sampler-Server ins System eindringt.
Mein Vorschlag: Versuch mal bei denen im Forum oder Direkt bei den
Programmierern eine Antwortwort zu bekommen.
F�r mich bleibt es ein R�tsel, warum die Shell-Konsole sich �ber Windows
problemlos schliessen l�st und �ber die gesendete WM_Close-Botschaft nicht.
Wenn man �ber das Fenstereigene Menue das Fenster schliesst, wird ja
auch eine WM_Close-Botschaft ans eigene Fenster geschickt.
Sehr merkw�rdig. :-(
Mfg
Georg H�bner
>> hier. Ich schaue morgen im B�ro nach, wenn es dich interessiert.
>
> Das w�rde mich aber trotzdem interessieren.
uses TLHelp32;
function GetPidFromExeName(const ExeName: string): cardinal;
var
Snapshot: THandle;
pe: TProcessEntry32;
begin
Result := 0;
pe.dwSize := SizeOf(pe);
Snapshot := CreateToolhelp32Snapshot(TH32CS_SnapProcess, 0);
if Process32First(Snapshot, pe) then
repeat
if AnsiLowerCase(ExeName) = AnsiLowerCase(pe.szExeFile) then
result := pe.th32ProcessID;
until (result<> 0) or not Process32Next(SnapShot, pe);
CloseHandle(SnapShot);
end;
Gru�, Alfred.
>>> hier. Ich schaue morgen im B�ro nach, wenn es dich interessiert.
Habe ich nat�rlich sofort ausprobiert.
Ergebnis: Handle ist <> 0
Handle :=GetPidFromExeName(S);
SendMessage(Handle,WM_CLOSE,0,0);
:(
Leider das gleiche Ergebnis.
> Handle :=GetPidFromExeName(S);
> SendMessage(Handle,WM_CLOSE,0,0);
GetPIDFromExeName liefert die ProcessID, kein Handle. Wenn du das
Fensterhandle brauchst:
uses TLHelp32;
var
WindowHandle: THandle;
function MyEnumWindowProc(AHandle: THandle; LParam: cardinal): boolean;
stdcall;
var
PID: cardinal;
begin
PID := 0;
GetWindowThreadProcessID(AHandle, PID);
Result := not (PID = LParam);
if not Result then
WindowHandle := AHandle;
end;
function GetWindowHandleByExeName(const AExeName: string): THandle;
var
SnapShot: THandle;
p: TProcessEntry32;
PID: cardinal;
begin
Result := 0;
WindowHandle := 0;
PID := 0;
p.dwSize := SizeOf(p);
SnapShot := CreateToolhelp32Snapshot(TH32CS_SnapProcess, 0);
try
if Process32First(SnapShot, p) then
repeat
if AnsiLowerCase(AExeName) = AnsiLowerCase(p.szExeFile) then
PID := p.th32ProcessID;
until (PID<>0) or not Process32Next(SnapShot, p);
EnumWindows(@MyEnumWindowProc, PID);
Result := WindowHandle;
finally
CloseHandle(SnapShot);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
WinExec('notepad.exe',SW_SHOWNORMAL);
end;
procedure TForm1.Button2Click(Sender: TObject);
var Hdl: THandle;
begin
Hdl := GetWindowHandleByExeName('notepad.exe');
if Hdl>0 then
PostMessage(Hdl,WM_CLOSE,0,0);
end;
HTH, ALfred
und genau das war's.
Das Teil wird endlich geschlossen.
Vielen vielen Dank Euch allen.
Es war wirklich essentiell wichtig.
Besten Dank! :-)
Mfg
Georg H�bner