AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Klasse zum Beenden eines Prozesses

Ein Thema von Luckie · begonnen am 18. Nov 2010 · letzter Beitrag vom 28. Mär 2011
Antwort Antwort
Seite 4 von 5   « Erste     234 5      
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#31

AW: Klasse zum Beenden eines Prozesses

  Alt 21. Nov 2010, 15:32
OK, überredet.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von stOrM
stOrM

Registriert seit: 7. Jun 2003
Ort: Mülheim an der Ruhr
434 Beiträge
 
Delphi 10.3 Rio
 
#32

AW: Klasse zum Beenden eines Prozesses

  Alt 21. Nov 2010, 17:18
Zitat:
Ähem, das ist Mumpitz, oder? Denn erstens braucht man mindestens die gleichen Rechte wie für TerminateProcess und zweitens wird diese Methode hier nicht zwischen Sitzungen funktionieren (Vista aufwärts). Sagen wir mal so, mit einem Datum von 1999 ist der Code mehr oder weniger "abgelaufen".
Naja als ich damals den Artikel über Winlogon Notification Packages geschrieben hatte stolperte ich immer wieder bei der Recherche über das besagte SafeTerminateProcess, was dann irgendwann meinen Jagdinstinkt geweckt hat Als ich dann die Erklärung dazu endlich gefunden hatte dachte ich mir gut, jetzt wo ich es weiss setzt ich es nach Delphi um. Mehr oder weniger hat die Umsetzung auf meinen Blog auch nicht zu sagen...
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#33

AW: Klasse zum Beenden eines Prozesses

  Alt 21. Nov 2010, 23:13
Madshi hatte glaube ich eine CreateRemoteThread, die auch über Sitzungen funkz. Naja, ich sehe schon wieder ne Menge Virenscanner, die da anschlagen würde.
Und dann einfach PostQuitMessage aufrufen muss auch nicht funkzen. Irgendein Verrückter könnte ein Fenster pro Thread gebaut haben, um Einfrieren zu verhindern.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Benutzerbild von Assarbad
Assarbad

Registriert seit: 8. Okt 2010
Ort: Frankfurt am Main
1.234 Beiträge
 
#34

AW: Klasse zum Beenden eines Prozesses

  Alt 21. Nov 2010, 23:17
Madshi hatte glaube ich eine CreateRemoteThread, die auch über Sitzungen funkz.
Den Code rückt er aber nicht so freizügig raus, soweit ich weiß. Damit eher ungeeignet als Basis für Michael's Klasse
Oliver
"... aber vertrauen Sie uns, die Physik stimmt." (Prof. Harald Lesch)
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#35

AW: Klasse zum Beenden eines Prozesses

  Alt 22. Nov 2010, 12:28
Aktuelle Version:
Delphi-Quellcode:
// Klasse zum Benden eines Processes mittels TerminateProcess
// Class for terminating a process via TerminateProcess
// Michael Puff [http://www.michael-puff.de]
// 2010-11-22

unit MpuKillProcessCls;

interface

uses
  Windows,
  Messages,
  SysUtils,
  TlHelp32;

type
  TOnTerminated = procedure(HasTerminated: Boolean; ProcessExefile: string) of object;
  TOnProcessNotFound = procedure(ProcessExefile: string) of object;
  TKillProcess = class(TObject)
  private
    FProcessExefile: string;
    FProcessID: Cardinal;
    FTimeOut: Cardinal;
    FOnTerminated: TOnTerminated;
    FOnProcessNotFound: TOnProcessNotFound;
    function GetProcessID: Cardinal;
    procedure SetProcessExefile(const Value: string);
    procedure SetPID(Value: Cardinal);
    function EnablePrivilege(const Privilege: string; fEnable: Boolean; out
      PreviousState: Boolean): DWORD;
  public
    property ProcessExefile: string read FProcessExefile write SetProcessExefile;
    property PID: Cardinal read FProcessID write SetPID;
    property TimeOutMSecs: Cardinal read FTimeOut write FTimeOut;
    property OnTerminated: TOnTerminated read FOnTerminated write FOnTerminated;
    property OnProcessNotFound: TOnProcessNotFound read FOnProcessNotFound write FOnProcessNotFound;
    constructor Create;
    procedure Kill;
  end;

implementation

constructor TKillProcess.Create;
begin
  FTimeOut := 0;
end;

function TKillProcess.EnablePrivilege(const Privilege: string;
  fEnable: Boolean; out PreviousState: Boolean): DWORD;
var
  Token: THandle;
  NewState: TTokenPrivileges;
  Luid: TLargeInteger;
  PrevState: TTokenPrivileges;
  Return: DWORD;
begin
  PreviousState := True;
  if (GetVersion() > $80000000) then
    // Win9x
    Result := ERROR_SUCCESS
  else
  begin
    // WinNT
    if not OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, Token) then
      Result := GetLastError()
    else
    try
      if not LookupPrivilegeValue(nil, PChar(Privilege), Luid) then
        Result := GetLastError()
      else
      begin
        NewState.PrivilegeCount := 1;
        NewState.Privileges[0].Luid := Luid;
        if fEnable then
          NewState.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
        else
          NewState.Privileges[0].Attributes := 0;
        if not AdjustTokenPrivileges(Token, False, NewState,
          SizeOf(TTokenPrivileges), PrevState, Return) then
          Result := GetLastError()
        else
        begin
          Result := ERROR_SUCCESS;
          PreviousState :=
            (PrevState.Privileges[0].Attributes and SE_PRIVILEGE_ENABLED <> 0);
        end;
      end;
    finally
      CloseHandle(Token);
    end;
  end;
end;

function TKillProcess.GetProcessID: Cardinal;
var
  ProcessSnapShot: THandle;
  pe32: TProcessEntry32;
  ProcessID: Cardinal;
begin
  ProcessID := 0;
  ProcessSnapShot := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);
  if ProcessSnapShot <> INVALID_HANDLE_VALUE then
  begin
    pe32.dwSize := SizeOf(ProcessEntry32);
    if Process32First(ProcessSnapShot, pe32) then
    begin
      while Process32Next(ProcessSnapShot, pe32) do
      begin
        if AnsiSameText(FProcessExefile, pe32.szExeFile) then
        begin
          ProcessID := pe32.th32ProcessID;
          Break;
        end;
      end;
    end
    else
    begin
      RaiseLastOSError;
    end;
  end
  else
  begin
    RaiseLastOSError;
  end;
  CloseHandle(ProcessSnapShot);
  if ProcessID = 0 then
  begin
    if Assigned(OnProcessNotFound) then
      OnProcessNotFound(FProcessExefile);
  end;
  Result := ProcessID;
end;

procedure TKillProcess.Kill;
var
  EnablePrivelege: DWORD;
  PreviousPriviliegeState: Boolean;
  ProcessHandle: Cardinal;
  WFSOReturnCode: DWORD;
begin
  FProcessID := GetProcessID;
  if FProcessID <> 0 then
  begin
    repeat
      EnablePrivelege := EnablePrivilege('SE_DEBUG_NAME', true, PreviousPriviliegeState);
      if EnablePrivelege <> 0 then
      begin
        ProcessHandle := OpenProcess(SYNCHRONIZE or PROCESS_TERMINATE, False, FProcessID);
        if ProcessHandle <> 0 then
        begin
          if TerminateProcess(ProcessHandle, 0) then
          begin
            WFSOReturnCode := WaitForSingleObject(ProcessHandle, FTimeOut);
            case WFSOReturnCode of
              WAIT_TIMEOUT:
                begin
                  if GetProcessID = 0 then
                  begin
                    if Assigned(OnTerminated) then
                      OnTerminated(True, FProcessExefile);
                  end
                  else
                  begin
                    if Assigned(OnTerminated) then
                      OnTerminated(False, FProcessExefile);
                    Exit;
                  end;
                  if FTimeOut > 0 then
                  begin
                    raise Exception.Create('Timeout');
                  end;
                end;
              WAIT_FAILED:
                begin
                  RaiseLastOSError;
                end;
              WAIT_OBJECT_0:
                begin
                  if Assigned(OnTerminated) then
                    OnTerminated(True, FProcessExefile);
                end;
            end;
          end
          else
          begin
            RaiseLastOSError;
          end;
          CloseHandle(ProcessHandle);
        end
        else
        begin
          RaiseLastOSError;
        end;
      end
      else
      begin
        raise Exception.Create(SysErrorMessage(GetLastError));
      end;
      FProcessID := GetProcessID;
    until FProcessID = 0;
  end;
end;

procedure TKillProcess.SetProcessExefile(const Value: string);
begin
  FProcessExefile := Value;
end;

procedure TKillProcess.SetPID(Value: Cardinal);
begin
  FProcessID := Value;
end;

end.
Demo:
Delphi-Quellcode:
program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  MpuKillProcessCls in 'MpuKillProcessCls.pas';

type
  TMain = class(TObject)
  public
    procedure OnTerminated(HasTerminated: Boolean; ProcessExefile: string);
    procedure OnProcessNotFound(ProcessExefile: string);
  end;

procedure TMain.OnProcessNotFound(ProcessExefile: string);
begin
  Writeln('Fehler. Process ' + ProcessExeFile + ' nicht gefunden.');
end;

procedure TMain.OnTerminated(HasTerminated: Boolean; ProcessExefile: string);
begin
  if HasTerminated then
    Writeln('Prozess ' + ProcessExefile + ' beendet')
  else
    Writeln('Fehler beim Beenden des Prozesses ' + ProcessExefile);
end;

var
  Main: TMain;
  KillProcess: TKillProcess;
begin
  Main := TMain.Create;
  try
    KillProcess := TKillProcess.Create;
    try
      try
        KillProcess.OnTerminated := Main.OnTerminated;
        KillProcess.OnProcessNotFound := Main.OnProcessNotFound;
        KillProcess.TimeOutMSecs := 5000;
        KillProcess.ProcessExefile := 'photofiltre.exe';
        //KillProcess.ProcessExefile := 'svchost.exe';
        //KillProcess.PID := 2696;
        KillProcess.Kill;
      except
        on E: Exception do
          Writeln(E.Message);
      end;
    finally
      KillProcess.Free;
    end;
  finally
    Main.Free;
  end;
  Readln;
end.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von HeikoAdams
HeikoAdams

Registriert seit: 12. Jul 2004
Ort: Oberfranken
661 Beiträge
 
FreePascal / Lazarus
 
#36

AW: Klasse zum Beenden eines Prozesses

  Alt 22. Nov 2010, 12:56
Ich habe den kompletten Thread jetzt nicht durchgelesen, aber was mir noch fehlen würde, wäre die Möglichkeit, Prozesse anhand des Fenstertitels zu beenden.
Jeder kann ein Held werden und Leben retten!
Einfach beim NKR oder der DKMS als Stammzellenspender registrieren! Also: worauf wartest Du noch?
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#37

AW: Klasse zum Beenden eines Prozesses

  Alt 22. Nov 2010, 13:59
Immer langsam mit den jungen Pferden. Man muss sich ja noch für Version 2 was aufheben.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Delphi-Laie

Registriert seit: 25. Nov 2005
1.474 Beiträge
 
Delphi 10.1 Berlin Starter
 
#38

AW: Klasse zum Beenden eines Prozesses

  Alt 29. Nov 2010, 16:28
Zitat:
if ... = true then
Das hätt ich jetzt nicht von dir erwartet.
Autsch, das passiert, wenn man alten Code per Copy and paste übernimmt.
Luckie, das wäre nicht nötig gewesen. Darob unterhielten wir uns schon wiederholt, erst vor Jahren (als ich zum ersten Mal darüber stolperte und sogar eine Diskussion dazu eröffnete, die recht lebhaft wurde), und dann vor einigen Monaten noch einmal im (gleichnamigen) Delphiforum.

Auch Dein

Delphi-Quellcode:
if Process32First(ProcessSnapShot, pe32) = true then
begin
  while Process32Next(ProcessSnapShot, pe32) = true do
  begin
    if pos(LowerCase(FProcessFile), LowerCase(pe32.szExeFile)) <> 0 then
      FProcessID := pe32.th32ProcessID;
   end;
end
ist ein Quentchen eleganter möglich (auch das schrieb ich Dir schon):

Delphi-Quellcode:
if Process32First(ProcessSnapShot, pe32) then
  repeat
  if pos(LowerCase(FProcessFile), LowerCase(pe32.szExeFile)) <> 0 then
      FProcessID := pe32.th32ProcessID
  until not Process32Next(ProcessSnapShot, pe32)
Das nur so als Ergänzung zu dem ansonsten guten und bewährten (und deshalb auch von mir ursprünglich so übernommenen Code).

Gruß Delph-Laie
  Mit Zitat antworten Zitat
Delphi-Laie

Registriert seit: 25. Nov 2005
1.474 Beiträge
 
Delphi 10.1 Berlin Starter
 
#39

AW: Klasse zum Beenden eines Prozesses

  Alt 29. Nov 2010, 16:33
@himitsu: Wenn ich mich recht erinnere steht pe32.szExeFile nur der Prozessname, also kein Pfad.
Unter Win9x der gesamte Pfad, unter NTx nur der Dateiname des Prozesse.

Für den Pfad benötigt man deshalb unter NTx beim ersten Eintrag des Modulschnappschusses den Eintrag "szExePath".
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#40

AW: Klasse zum Beenden eines Prozesses

  Alt 29. Nov 2010, 17:33
@Delphi-Laie: Du beziehst dich da gerade auf veralteten Code.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 4 von 5   « Erste     234 5      


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 02:42 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