Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   In welchem Pfad läuft ein Prozess? (https://www.delphipraxis.net/198276-welchem-pfad-laeuft-ein-prozess.html)

Marco Steinebach 19. Okt 2018 12:22

In welchem Pfad läuft ein Prozess?
 
Hallo zusammen,
gibt es keine Möglichkeit, auf einfache weise, folgendes herauszufinden:
ist eine Exe gestartet? (ich weiß nicht, ob die immer ein Window-Handle hat).
Wenn ja, in welchem Pfad liegt sie?
Ich will eigentlich nicht erst noch groß ToolHelp oder sonstwas installieren, das muß doch auch mit Bordmitteln gehen?
Ich will auch nix ändern sondern nur wissen, ob mein Screenreader (jfw.exe) läuft und wenn ja, in welchem Verzeichnis sie liegt.
Ich bräuchte mal 'n tip, bitte!

Herzliche Grüße
Marco

Luckie 19. Okt 2018 12:24

AW: In welchem Pfad läuft ein Prozess?
 
Das wäre ein Anfang: https://docs.microsoft.com/en-us/win...help32snapshot

Uwe Raabe 19. Okt 2018 12:42

AW: In welchem Pfad läuft ein Prozess?
 
Ich verwende für sowas gerne die madCollection. Damit lässt sich das ganz einfach ermitteln: http://help.madshi.net/Processes.htm#IProcess
Delphi-Quellcode:
// Example:
Process('explorer.exe').ExeFile -> 'C:\Windows\Explorer.exe'

KodeZwerg 19. Okt 2018 13:35

AW: In welchem Pfad läuft ein Prozess?
 
Mit folgender funktion hast Du 2 Ergebnisse auf einmal, wenn TRUE dann ist es im selben Verzeichnis gestartet, wenn Count > 0 dann kannst Du alle geladenen Prozesse mit gleichen Dateinamem abrufen.
Sorry aber ein paar uses braucht man schon dafür.
Delphi-Quellcode:
uses TlHelp32, PsAPI;

{*
*  Procedure : KillProcess
*  Author   : Michael Puff
*  Date     : 2006-09-15
*  Terminates a process identified by its PID
*}
function KillProcess(dwProcID, Wait: DWORD): Integer;
var
  hProcess : Cardinal;
  dw : DWORD;
begin
  // open the process and store the process-handle
  hProcess := OpenProcess(SYNCHRONIZE or PROCESS_TERMINATE, False, dwProcID);
  // kill it
  if hProcess <> 0 then
  begin
    dw := Integer(TerminateProcess(hProcess, 1));
    if dw <> 0 then
    begin
      // TerminateProcess returns immediately, so we have to verify the result via
      // WaitForSingleObject
      dw := WaitForSingleObject(hProcess, Wait);
      if dw = WAIT_FAILED then
        dw := GetLastError;
    end
    else // TerminateProcess = 0
      dw := GetLastError;
    CloseHandle(hProcess);
  end
  else // hProcess = INVALID_HANDLE_VALUE
    dw := GetLastError;
  result := dw;
end;

function ProcessExists(const AFileName: string; var FoundFiles: TStringList; const IncludeHost: Boolean = False; const Kill: Boolean = False): Boolean;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
  fullPath: string;
  myHandle: THandle;
  myPID: DWORD;
  OwnPID: Cardinal;
begin
  FoundFiles := TStringList.Create;
  OwnPID := GetCurrentProcessId;
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  Result := False;
  while Integer(ContinueLoop) <> 0 do
  begin
    if UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExtractFileName(AFileName)) then
    begin
      myPID := FProcessEntry32.th32ProcessID;
        if (Kill = True) then
          if (OwnPID <> myPID) then
            KillProcess(myPID, 500); // Wenn Du hier noch eine Null ranhängst, gibst Du der Kill Funktion 5 Sekunden Zeit zum Abschluss zu kommen
      myHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, myPID);
      if myHandle <> 0 then
      try
        SetLength(fullPath, MAX_PATH);
        if GetModuleFileNameEx(myHandle, 0, PChar(fullPath), MAX_PATH) > 0 then
        begin
          SetLength(fullPath, StrLen(PChar(fullPath)));
          if UpperCase(ExtractFilename(fullPath)) = UpperCase(ExtractFilename(AFileName)) then
            if (IncludeHost=False) then
              begin
                if (OwnPID <> myPID) then
                  FoundFiles.Add(fullPath);
              end
              else
                FoundFiles.Add(fullPath);
          if UpperCase(fullPath) = UpperCase(AFileName) then
            Result := True;
        end else
          fullPath := '';
      finally
        CloseHandle(myHandle);
      end;
      {if Result then
        Break;}
    end;
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
  end;
  CloseHandle(FSnapshotHandle);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  s: TStringList;
  i: Integer;
begin
  Memo1.Clear;
  processExists(Application.ExeName,S, Checkbox1.Checked, Checkbox2.Checked);
  for i := 0 to S.Count -1 do
    Memo1.Lines.Add(S.Strings[i]);
end;
/edit
nun ist noch eine Abfrage enthalten ob der Host-Prozess berücksichtigt werden soll, nur bei TRUE ist der in der Liste enthalten.

/edit
nun kann es alle "nicht-Hosts" auch killen :-)

KodeZwerg 19. Okt 2018 16:03

AW: In welchem Pfad läuft ein Prozess?
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1416121)
Ich verwende für sowas gerne die madCollection. Damit lässt sich das ganz einfach ermitteln: http://help.madshi.net/Processes.htm#IProcess
Delphi-Quellcode:
// Example:
Process('explorer.exe').ExeFile -> 'C:\Windows\Explorer.exe'

Hallo Uwe, Klasse Tipp von Dir (wie gewohnt :)), ich habe mich da mal umgeschaut, die IProcesses Methode würde da dann wohl eher zu tragen kommen (TE meinte was das mehrere Instanzen vorhanden sein könnten), ich hoffe den Source dazu kann man einsehen, der würde mich schon Interessieren, schaut sehr lecker aus.

An TE:
Vielleicht wäre es auch besser eine "OnlyOneInstance" funktionalität Deinem Programm beizubringen? Das würde jedenfalls diese Prozess Suche abkürzen und eher zutreffend sein. Vielleicht mit einem MUTEX in .DPR?
Je nach dem was man erreichen will.
Inhaltlich hast Du auf jedenfall zwei gute Lösungen die Dir alle Prozesse mit gewünschtem Dateinamen auflisten könnten.

Uwe Raabe 19. Okt 2018 16:08

AW: In welchem Pfad läuft ein Prozess?
 
Zitat:

Zitat von KodeZwerg (Beitrag 1416139)
ich hoffe den Source dazu kann man einsehen, der würde mich schon Interessieren, schaut sehr lecker aus.

Gegen einen kleinen Obolus :-D gibt es auch die Sourcen: http://www.madshi.net/madExceptShop.htm
Das Geld ist aber definitiv gut angelegt.

DieDolly 19. Okt 2018 16:33

AW: In welchem Pfad läuft ein Prozess?
 
Klein würde ich den Obolus nicht nennen.
Die Mehrwertsteuer kommt noch oben drauf. Die 159€ die da stehen sind nur zum anlocken da.

KodeZwerg 19. Okt 2018 16:55

AW: In welchem Pfad läuft ein Prozess?
 
LOL madExcept 4.0.20, nein das wollte ich nicht kaufen (ich bin bei der Konkurenz seit Jahren, vielleicht haben die ja was ähnliches, so intern habe ich mich damit noch nicht viel beschäftigt, EurekaLog ist verbaut in Version 7, seit dem hat CRC ne macke, na egal, alles wird gut^^)

für Interessierte, ich habe da oben noch ne Host-Prozess ability eingepflanzt damit eben dieser nicht in der Liste erscheint, ich weiß ja noch nicht was der TE mit dieser Information anfängt (eine Dateiliste zu einem Dateinamen)

KodeZwerg 19. Okt 2018 19:16

AW: In welchem Pfad läuft ein Prozess?
 
Ebenfalls von Moderator Luckie dieses Mutex Beispiel, falls es darauf hinaus laufen sollte.

Oben wäre nun auch eine TerminateProcess funktion enthalten :-)

Luckie 19. Okt 2018 20:21

AW: In welchem Pfad läuft ein Prozess?
 
Da gräbt jetzt aber einer in meiner dunklen Vergangenheit. :mrgreen:

KodeZwerg 19. Okt 2018 20:49

AW: In welchem Pfad läuft ein Prozess?
 
Zitat:

Zitat von Luckie (Beitrag 1416150)
Da gräbt jetzt aber einer in meiner dunklen Vergangenheit. :mrgreen:

[ironie]Ein Teil Deines Codes verunsichert mich[/ironie] aber verwenden mag ich ihn dennoch 8-)
Danke für Deine tolle Seite, mit viel Augenmerk auf schmale Sachen :thumb:

Luckie 19. Okt 2018 21:04

AW: In welchem Pfad läuft ein Prozess?
 
Danke. Nur ist da lange nichts mehr passiert. ich habe etwa den Anschluss verloren. Deswegen sind die Codes mit Vorsicht zu genießen. Besonders was Unicode angeht.

DieDolly 19. Okt 2018 21:14

AW: In welchem Pfad läuft ein Prozess?
 
Ich finde ein Mutex ist nur dazu geeignet, den doppelten Start eines Programms zu verhindern.
Für alles andere sollte man spezifische Lösungen vorziehen.

KodeZwerg 19. Okt 2018 21:26

AW: In welchem Pfad läuft ein Prozess?
 
In meiner Eigenen Mutex variante passiert ein wenig mehr als wie bei dem Sample was ich verlinkt habe.

Bei Interesse kann ich es eventuell Suchen, ich habe da mehrere Switches eingebaut so das man verschiedene Dinge damit machen kann.
1. das reguläre "NurEineInstanz" wie aus dem Code von Luckie
2. zu alter Instanz wechseln, im Vordergrund
3. alte Instanz töten bevor neue lädt
4. alte Instanz ein Kommando geben (wenn app dateinamen braucht zum beispiel, übergebe ich namen an alte Instanz und refresh diese)
5. endlos neue Instanzen schaffen
6. mehr war mir damals nicht eingefallen glaube ich :-)

allerdings alles querbeet unsortiert unschön nur funktional, könnte man sicherlich auch schön verpacken, ich war damals zu faul und bin es heute immer noch :)

DieDolly 20. Okt 2018 10:40

AW: In welchem Pfad läuft ein Prozess?
 
Zitat:

2. zu alter Instanz wechseln, im Vordergrund
3. alte Instanz töten bevor neue lädt
Wenn du das mit deiner ProcessExists() machst, dann hast du bei Nr 3 aber ein Grundproblem:
wenn du den Code nicht in der DPR noch vor Erzeugen der Forms aufrufst, hat dein Programm schon viele unnötige Arbeit erledigt.

KodeZwerg 20. Okt 2018 12:00

AW: In welchem Pfad läuft ein Prozess?
 
dass das alles optionen sind ist dir schon bewusst, ja? das man nicht alle optionen auf einmal anwenden kann hoffentlich auch.
man könnte es noch mehr erweitern mit logging und all so was, war hier nicht nötig.

ohne in forms/application/messages einzugreifen würde es mir schwer fallen einen dateinamen rüberzuschaffen und app anzustubsen auch was damit zu machen, also nein, nicht nur die .dpr ist betroffen.

bei mir ists halt an mehreren ecken verankert da es nicht nur wie du schreibst "Ich finde ein Mutex ist nur dazu geeignet, den doppelten Start eines Programms zu verhindern." diesen zweck erfüllt sondern halt mehr.
es wird nicht nur verhindert sondern erweitert, was im endeffekt passieren soll geben bei mir optionen vor.

wie dem auch sei, ich bin happy damit da es all meine bedürfnisse an so etwas abdeckt. jeder so wie er mag :-)

Marco Steinebach 20. Okt 2018 14:18

AW: In welchem Pfad läuft ein Prozess?
 
Hallo zusammen,
und erstmal ganz, ganz herzlichen Dank für eure Antworten.
Also, nur zur Klärung: einen Mutex hat mein Prog ohnehin schon, ich will auch nicht wissen, ob mein Programm selbst läuft, sondern ob der User einen sog. ScreenReader gestartet hat, und wenn ja, in welchem Verzeichnis der läuft, damit ich dann, so der User will, dafür ein Skript installieren kann. (nein, das ist ein Skript für den ScreenReader, kein Virus-Ding. ;-).
Aber das kommt davon, wenn man erst winselt, und dann guckt,ich dachte, dass die ToolHelp32 eine Extra-Komponente ist, die dann, wahrscheinlich, nicht mehr mit meinem alten D5 Pro läuft - aber siehe da, ist es gar nicht. ;-)

So. Und jetzt geht's ans Code verstehen!

Herzlichen Dank nochmal und viele Grüße
Marco

Marco Steinebach 20. Okt 2018 20:26

AW: In welchem Pfad läuft ein Prozess?
 
Und nochmal,
Wenn man in Michaels Code
Code:
if GetModuleFileNameEx (myHandle, 0, PChar(fullPath), MAX_PATH) > 0 then}
durch
Code:
var
  fLen: cardinal;
   ...
  fLen := max_path;
  if QueryFullProcessImageName (myHandle, 0, PChar(fullPath), @len) then
ersätzt, geht das ganze auch für 64-Bit-Prozesse, die von einem 32-Bit-Programm abgefragt werden.
Dazu noch
Code:
function QueryFullProcessImageName( hProcess: THandle;
    dwFlags: DWORD;
    lpExeName: PChar;
    nSize: PDWORD): BOOL; stdcall;
    external kernel32 name 'QueryFullProcessImageNameA';
in die Unit einfügen.

Viele Grüße
Marco

KodeZwerg 20. Okt 2018 21:21

AW: In welchem Pfad läuft ein Prozess?
 
Zitat:

Zitat von Marco Steinebach (Beitrag 1416210)
Und nochmal, Wenn man in Michaels Code

Michaels Code ist die KillProcess() Funktion.
Zitat:

Zitat von Marco Steinebach (Beitrag 1416210)
external kernel32 name 'QueryFullProcessImageNameA';

Da ich nun weiß worum es Dir mehr oder weniger geht und ich die ANSI Version gelesen habe, war ich so frei es noch mal zu überarbeiten, etwas gezielter für Deine Bedürfnisse:

Delphi-Quellcode:
function PidToFilename(const TargetPID: THandle): string;
type
  TQueryFullProcessImageName = function(hProcess: THandle; dwFlags: DWORD; lpExeName: PChar; nSize: PDWORD): BOOL; stdcall;
var
  hProcess: THandle;
  TargetName: array [0 .. MAX_PATH - 1] of Char;
  QueryFullProcessImageName: TQueryFullProcessImageName;
  nSize: cardinal;
begin
  Result := '';
  hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, TargetPID);
  if hProcess <> 0 then
    try
      if GetModuleFileNameEX(hProcess, 0, TargetName, MAX_PATH) <> 0 then Result := TargetName
      else if Win32MajorVersion >= 6 then
      begin
        nSize := MAX_PATH;
        ZeroMemory(@TargetName, MAX_PATH);
        @QueryFullProcessImageName := GetProcAddress(GetModuleHandle('kernel32'), 'QueryFullProcessImageNameW');
        if Assigned(QueryFullProcessImageName) then
          if QueryFullProcessImageName(hProcess, 0, TargetName, @nSize) then Result := TargetName
      end;
    finally
      CloseHandle(hProcess);
    end;
end;

function ProcessExists(const AFileName: string; var FoundFiles: TStringList; out HostIndex: Integer): Boolean;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
  fullPath: string;
  myHandle: THandle;
  myPID: DWORD;
  OwnPID: Cardinal;
begin
  HostIndex := -1;
  FoundFiles := TStringList.Create;
  OwnPID := GetCurrentProcessId;
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  Result := False;
  while Integer(ContinueLoop) <> 0 do
  begin
    if UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExtractFileName(AFileName)) then
    begin
      myPID := FProcessEntry32.th32ProcessID;
      fullPath := PidToFilename(myPID);
      FoundFiles.Add(fullPath);
      if (myPID = OwnPID) then HostIndex := FoundFiles.Count-1;
    end;
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
  end;
  CloseHandle(FSnapshotHandle);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  s: TStringList;
  i, idx: Integer;
begin
  Memo1.Clear;
  processExists(Application.ExeName,S, idx);
  for i := 0 to S.Count -1 do
    Memo1.Lines.Add(S.Strings[i]);
  if (idx >= 0) then Memo1.Lines.Add('Host is '+S.Strings[idx]);
end;
So sollte es auch mit Unicode hoffentlich zurecht kommen.
Als Rückgabe hast Du nach wie vor die Liste plus den Index vom Host, vielleicht hilft es Dir.

KodeZwerg 21. Okt 2018 08:11

AW: In welchem Pfad läuft ein Prozess?
 
Ps: Für Dein Delphi 5 musst Du Char mit WideChar und String mit WideString ersetzen (ich kann es nicht prüfen da ich version 5 nicht habe)

KodeZwerg 21. Okt 2018 08:51

AW: In welchem Pfad läuft ein Prozess?
 
Zitat:

Zitat von Schokohase (Beitrag 1416223)
Zitat:

Zitat von KodeZwerg (Beitrag 1416221)
Ps: Für Dein Delphi 5 musst Du Char mit WideChar und String mit WideString ersetzen (ich kann es nicht prüfen da ich version 5 nicht habe)

Das reicht leider nicht aus. Wenn man explizit Ansi oder Wide haben möchte, dann muss man auch ganz explizit die A oder W Variante der API aufrufen.

Och, ich dachte das ich das mache mit dem GetProcAddress(GetModuleHandle('kernel32'), 'QueryFullProcessImageNameW'); Befehl.

KodeZwerg 21. Okt 2018 09:09

AW: In welchem Pfad läuft ein Prozess?
 
ahh ich verstehe, also delphi 5 nimmt da dann wohl die ansi wo hingegen meins automatisch wide verwendet, ich werde es nochmal überarbeiten, danke!

KodeZwerg 21. Okt 2018 09:30

AW: In welchem Pfad läuft ein Prozess?
 
Delphi-Quellcode:
function PidToFilename(const TargetPID: THandle): WideString;
type
  TQueryFullProcessImageNameW = function(AProcess: THANDLE; AFlags: DWORD; lpExeName: PWideChar; var nSize: DWORD): BOOL; stdcall;
var
  hProcess: THandle;
  TargetName: array [0 .. MAX_PATH - 1] of WideChar;
  QueryFullProcessImageNameW: TQueryFullProcessImageNameW;
  nSize: DWORD;
begin
  Result := '';
  hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, TargetPID);
  if hProcess <> 0 then
    try
      if GetModuleFileNameExW(hProcess, 0, TargetName, MAX_PATH) <> 0 then Result := TargetName
      else if Win32MajorVersion >= 6 then
      begin
        nSize := MAX_PATH;
        ZeroMemory(@TargetName, MAX_PATH);
        @QueryFullProcessImageNameW := GetProcAddress(GetModuleHandle('kernel32'), 'QueryFullProcessImageNameW');
        if Assigned(QueryFullProcessImageNameW) then
          if QueryFullProcessImageNameW(hProcess, 0, TargetName, nSize) then Result := TargetName
      end;
    finally
      CloseHandle(hProcess);
    end;
end;

function ProcessExists(const AFileName: WideString; var FoundFiles: TStringList; out HostIndex: Integer): Boolean;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
  fullPath: WideString;
  myPID: DWORD;
  OwnPID: Cardinal;
begin
  HostIndex := -1;
  FoundFiles := TStringList.Create;
  OwnPID := GetCurrentProcessId;
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  Result := False;
  while Integer(ContinueLoop) <> 0 do
  begin
    if UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExtractFileName(AFileName)) then
    begin
      myPID := FProcessEntry32.th32ProcessID;
      fullPath := PidToFilename(myPID);
      FoundFiles.Add(fullPath);
      if myPID = OwnPID then
      begin
        HostIndex := FoundFiles.Count-1;
        Result := True;
      end;
    end;
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
  end;
  CloseHandle(FSnapshotHandle);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  s: TStringList;
  i, idx: Integer;
begin
  Memo1.Clear;
  processExists(Edit1.Text, S, idx);
  for i := 0 to S.Count -1 do
    Memo1.Lines.Add(S.Strings[i]);
  if (idx >= 0) then Memo1.Lines.Add('Host is '+S.Strings[idx]);
end;
In der Hoffnung das ich dieses mal alles berücksichtigt habe was man so alles berücksichtigen sollte für Delphi's vor 2009.

Daniel 21. Okt 2018 10:05

AW: In welchem Pfad läuft ein Prozess?
 
Ihr beiden klärt das bitte per PN.

Marco Steinebach 23. Okt 2018 13:07

AW: In welchem Pfad läuft ein Prozess?
 
Hallo Kodezwerg, hallo zusammen,
erstmal entschuldigung dafür, dass ich deinen Code fälschlicherweise Michael zugeschlagen habe. Sorry!
Ich hatte ihn auch schon überarbeitet, aber deine Version ist definitiv schöner, alleine schon, weil die Funktion aus Kernel32 erst in der Funktion eingebunden wird.
Funktioniert auch unter D5 prima - vielen Dank.

Ein kleiner Fehler ist aber noch drin, die Funktion "ProcessExists" gibt nur dann true zurück, wenn man auch nach dem eigenen Programm sucht, sonst nicht.

Aber jetzt habe ich doch noch eine Frage - dieses Windows-Gedöns bringt mich nochmal um:
Zwei rechner, beide Win7 64-bit, beide Nutzer der als Administrator aufgeführt wird.
Bei dem einen liefert ProcessExists zurück was es soll, nämlich den Pfad samt dem Dateinamen der exe.
Bei dem anderen gibt es keinen Fehler, aber das Rückgabe-Ergebnis ist leer. Führe ich mein Prog als Administrator aus (also Kontextmenü alsAdministrator ausführen) funktioniert alles?
Hä? Irgend eine Idee?

Herzliche Grüße
Marco

KodeZwerg 23. Okt 2018 13:31

AW: In welchem Pfad läuft ein Prozess?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Marco Steinebach (Beitrag 1416401)
erstmal entschuldigung dafür, dass ich deinen Code fälschlicherweise Michael zugeschlagen habe. Sorry!

Das geht schon in Ordnung, ich wollte nur nicht das fehler dem Luckie nachgesagt werden, seine funktion arbeitet 1A.
Orignal stammt glaub ich von StackOverflow, ich habs nur für Dich angepasst.
Zitat:

Zitat von Marco Steinebach (Beitrag 1416401)
Ein kleiner Fehler ist aber noch drin, die Funktion "ProcessExists" gibt nur dann true zurück, wenn man auch nach dem eigenen Programm sucht, sonst nicht.

Das ist Sinn und Zweck vom Result. True = einer der gefundenen Prozesse ist der Host.
Um zu prüfen nach einem Ja/Nein nimm einfach den Count von der Liste, wenn der höher als null = dann wurde was gefunden.
Zitat:

Zitat von Marco Steinebach (Beitrag 1416401)
Hä? Irgend eine Idee?

Ich müsste sehen wie Du den Code momentan verarbeitest, gibt es eine Demo?
Bei mir unter Windows 10 benötige ich keine Admin Rechte um diese Funktion aufzurufen.

/edit
Wenn möglich, teste mal bitte dieses Programm.
Der Code ist identisch nur das ich da nach allem Suche. Zum ausführen braucht man keine speziellen Rechte. (Terminate Knopf hat noch keine Funktion)
So schauts momentan aus:
Anhang 50129

Marco Steinebach 26. Okt 2018 13:29

AW: In welchem Pfad läuft ein Prozess?
 
Hallo Kodezwerg, hallo zusammen,
Ich bin ein bißchen weiter:
OpenProcess liefert als Fehler (5) zurück, also Access denied. Wenn ich mein Prog von der IDE aus starte, läuft alles, da muß ich aber beim Start auch die UAC abnichen. Zu deutsch: mein Prog hat nicht genug Rechte, um die Process-Info abzufragen.
Dein ProcessLister läuft ohne weiteres - keine Ahnung, warum das so ist.
Kann man einem Programm, außer via Manifest, denn andere Rechtezum Ausführen iener Funktion geben?
Viele Grüße
Marco

KodeZwerg 26. Okt 2018 16:58

AW: In welchem Pfad läuft ein Prozess?
 
Hallo nochmal, ohne zu sehen wie Du den Code verarbeitest ist es schwer zu sagen was bei Dir falsch läuft.
Es kann auch gut möglich sein das Du versuchst auf System-Prozesse zuzugreifen (die sieht man in meinem Process Lister nämlich erst gar nicht, weil eben solche mit "Verboten" "Fehler" zurückkommen.)

Ich selbst kann mein Programm nicht in der Ide ausführen da ich bewusst auf Exceptions reagiere die mir mitteilen, Hallo Kollege, das da geht nicht, ist ein System-Process.
(dafür benötigt man anderen Code um Informationen zu bekommen.)

Wenn Dich das Thema Interessieren sollte, auf SourceForge gibts ein Projekt Namens ProcessHacker, samt Source Code.

Ohne Code von Dir zu sehen kann ich nur sagen was die Glaskugel mir erzählt, der Fehler sitzt vorm Rechner :-)

Wenn ein Programm beim Aufrufen bereits Admin-Rechte benötigt ist Manifest der optimale Weg das zu erreichen, wenn Du damit auch Probleme haben solltest, bitte einen neuen Thread erstellen und Dir wird geholfen.

Um reguläre Processe und dessen Informationen abzufragen bedarf es keiner speziellen Rechte, diese Informationen stehen jedem Programm frei zur Verfügung.

HolgerX 26. Okt 2018 17:56

AW: In welchem Pfad läuft ein Prozess?
 
Hmm..

Könnte es sein, das deine EXE etwas im Namen, wie Setup/Install.. enthält, oder etwas, was Windows dazu bewegt die UNC Frage zu stellen?

Dann wird dieser Process wohl als protected processes eingestuft.


https://docs.microsoft.com/en-us/win...-access-rights

Zitat:

Protected Processes
Windows Vista introduces protected processes to enhance support for Digital Rights Management. The system restricts access to protected processes and the threads of protected processes.

The following standard access rights are not allowed from a process to a protected process:

**DELETE** **READ\_CONTROL** **WRITE\_DAC** **WRITE\_OWNER**
The following specific access rights are not allowed from a process to a protected process:

**PROCESS\_ALL\_ACCESS** **PROCESS\_CREATE\_PROCESS** **PROCESS\_CREATE\_THREAD** **PROCESS\_DUP\_HANDLE** **PROCESS\_QUERY\_INFORMATION** **PROCESS\_SET\_INFORMATION** **PROCESS\_SET\_QUOTA** **PROCESS\_VM\_OPERATION** **PROCESS\_VM\_READ** **PROCESS\_VM\_WRITE**
The PROCESS_QUERY_LIMITED_INFORMATION right was introduced to provide access to a subset of the information available through PROCESS_QUERY_INFORMATION.

Für GetModuleFileNameEx wird 'PROCESS_QUERY_INFORMATION and PROCESS_VM_READ' benötigt, jedoch für QueryFullProcessImageName nur mindestens PROCESS_QUERY_LIMITED_INFORMATION.

Ich habe mal die Funktion PidToFilename umgeschrieben, so dass ab Vista nicht mehr GetModuleFileNameEx sondern immer QueryFullProcessImageName mit den reduzierten Rechten von PROCESS_QUERY_LIMITED_INFORMATION verwendet wird..


Delphi-Quellcode:
const
  PROCESS_QUERY_LIMITED_INFORMATION = $1000;

function PidToFilename(const TargetPID: THandle): WideString;
type
  TQueryFullProcessImageNameW = function(hProcess: THandle; dwFlags: DWORD; lpExeName: PWideChar; nSize: PDWORD): BOOL; stdcall;
var
  hProcess: THandle;
  TargetName: WideString;
  QueryFullProcessImageNameW: TQueryFullProcessImageNameW;
  nSize: cardinal;
begin
  Result := '';
  nSize := MAX_PATH;
  SetLength(TargetName, nSize);
  if Win32MajorVersion >= 6 then begin
    hProcess := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, TargetPID);
    if hProcess <> 0 then begin
      try
        @QueryFullProcessImageNameW := GetProcAddress(GetModuleHandle('kernel32'), 'QueryFullProcessImageNameW');
        if Assigned(QueryFullProcessImageNameW) then
          if QueryFullProcessImageNameW(hProcess, 0, PWideChar(TargetName), @nSize) then
            Result := PWideChar(TargetName);
      finally
        CloseHandle(hProcess);
      end;
    end;
  end else begin
    hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, TargetPID);
    if hProcess <> 0 then
      try
        if GetModuleFileNameExW(hProcess, 0, PWideChar(TargetName), nSize) <> 0 then
          Result := PWideChar(TargetName);
    finally
      CloseHandle(hProcess);
    end;
  end;
end;

KodeZwerg 26. Okt 2018 18:31

AW: In welchem Pfad läuft ein Prozess?
 
Zitat:

Zitat von HolgerX (Beitrag 1416826)
Ich habe mal die Funktion PidToFilename umgeschrieben, so dass ab Vista nicht mehr GetModuleFileNameEx sondern immer QueryFullProcessImageName mit den reduzierten Rechten von PROCESS_QUERY_LIMITED_INFORMATION verwendet wird..


Delphi-Quellcode:
const
  PROCESS_QUERY_LIMITED_INFORMATION = $1000;

function PidToFilename(const TargetPID: THandle): WideString;
type
  TQueryFullProcessImageNameW = function(hProcess: THandle; dwFlags: DWORD; lpExeName: PWideChar; var nSize: PDWORD): BOOL; stdcall;

Dankeschön, sieht gut aus :thumb: werde ich fast so übernehmen, ich lass das var vorm nSize drinnen, Api sagt
Zitat:

On success, receives the number of characters written to the buffer, not including the null-terminating character.

Marco Steinebach 26. Okt 2018 21:40

AW: In welchem Pfad läuft ein Prozess?
 
Huhu Kodezwerg,
Code? Völlig langweilig:
Code:
  processExists (edit1.text, l, idx);
  memo1.lines.Add (format ('Name: %s', [edit1.text]));
  if l.count > 0 then
    memo1.lines.add (format ('Pfad: %s', [l[0]]))
  else
    memo1.lines.Add ('Pfad nicht ermittelt');
  l.free;
Einfach eine Form mit einem Edit für den Prozess-Namen, einem Memo für die Ausgabe und einem Button zum Test, dessen onClick-Methode oben steht.
Für z.B. Explorer.exe funktioniert das wunderbar, nur bei meinem ScreenReader weigert er sich.
Gibt's noch irgendwelche Flags oder so mit denen man rausfinden könnte, warum er sich bei denen weigert?
Viele Grüße
Marco

KodeZwerg 26. Okt 2018 22:25

AW: In welchem Pfad läuft ein Prozess?
 
Komisch, also wenn bei Dir Edit1.Text einen guten Namen wie "Explorer.exe" annimmt aber "xyz.exe" nicht, obwohl mein processlister "xyz.exe" anzeigen kann, da fällt mir nichts weiter zu ein.
Ich nutz identischen Code zum ermitteln der Prozesse, da passiert genau das gleiche, nur das ich in der Schleife alle Prozesse sammel und System-Prozesse gleich rauswerfe (die sind bei Dir noch enthalten), das ist der einzige Unterschied.

So hier müsste es klappen das bei systemprozessen du keine AV bekommst, habs grad nicht getestet, nur hier im editor.
Delphi-Quellcode:
function ProcessExists(const AFileName: WideString; var FoundFiles: TStringList; out HostIndex: Integer): Boolean;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
  fullPath: WideString;
  myPID: DWORD;
  OwnPID: Cardinal;
begin
  HostIndex := -1;
  FoundFiles := TStringList.Create;
  OwnPID := GetCurrentProcessId;
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  Result := False;
  while Integer(ContinueLoop) <> 0 do
  begin
    Try
    if UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExtractFileName(AFileName)) then
    begin
      myPID := FProcessEntry32.th32ProcessID;
      fullPath := PidToFilename(myPID);
      FoundFiles.Add(fullPath);
      if myPID = OwnPID then
      begin
        HostIndex := FoundFiles.Count-1;
        Result := True;
      end;
    end;
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
    Except
      ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
    End;
  end;
  CloseHandle(FSnapshotHandle);
end;

HolgerX 27. Okt 2018 07:46

AW: In welchem Pfad läuft ein Prozess?
 
Hmm..



Zitat:

Zitat von KodeZwerg (Beitrag 1416829)

Dankeschön, sieht gut aus :thumb: werde ich fast so übernehmen, ich lass das var vorm nSize drinnen, Api sagt

Ich denke entweder

var nSize: DWORD

oder

nSize: PDWORD


(Beides liefert die Länge zurück)

aber

var nSize: PDWORD

dürfte doppelt gemoppelt sein ;)

KodeZwerg 27. Okt 2018 08:15

AW: In welchem Pfad läuft ein Prozess?
 
hab den pointer überlesen *whoops*, klar ohne.

Marco Steinebach 27. Okt 2018 19:25

AW: In welchem Pfad läuft ein Prozess?
 
Hallo zusammen,
Jep! Die "eingeschränkten Rechte" waren die Lösung.
Ich bin auch gerade darauf gestoßen, aber ihr wart schneller!
Vielen herzlichen Dank fürs Lösen helfen.
Herzliche Grüße
Marco


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:03 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