Delphi как найти процесса

Please note I have only accepted this solution so that a full delphi code solution is accepted, all due thanks to Jk though for pointing me on the correct path.

Ok, I’ve been able to figure out how to use the answer by Jk and have come up with this solution in delphi.

For reference, this is the link provided by Jk:

QueryServiceStatusEx

My Solution:

unit Demo;

interface

uses
  Windows, Forms, SysUtils,
  StdCtrls, WinSvc, Controls, Classes;

type

  //Form for basic demo usage
  TForm6 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  end;

  //Record defined for use as return buffer
  _SERVICE_STATUS_PROCESS = record
    dwServiceType: DWORD;
    dwCurrentState: DWORD;
    dwControlsAccepted: DWORD;
    dwWin32ExitCode: DWORD;
    dwServiceSpecificExitCode: DWORD;
    dwCheckPoint: DWORD;
    dwWaitHint: DWORD;
    dwProcessId: DWORD;
    dwServiceFlags: DWORD;
  end;
  //Function Prototype
  function QueryServiceStatusEx(
  SC_HANDLE: SC_Handle;
  SC_STATUS_TYPE: Cardinal;
  out lpBuffer: _SERVICE_STATUS_PROCESS;
  cbBufSize: DWORD;
  out pcbBytesNeeded: LPDWORD
  ): BOOL; stdcall;


  //internal setup function
  function GetPid(sService: String; sMachine: String = '') : Cardinal;
var
  Form6: TForm6;

implementation

{$R *.dfm}
const
  // windows api library
  advapi32 = 'advapi32.dll';
  //define the api call
  function QueryServiceStatusEx;   external advapi32 name 'QueryServiceStatusEx';

//for demo usage
procedure TForm6.Button1Click(Sender: TObject);
begin
  Memo1.Lines.Add(IntToStr(Integer(GetPid('Service'))))
end;


function GetPid(sService: String; sMachine: String = '') : Cardinal;
var
  schm,
  schs: SC_Handle;
  SC_STATUS_TYPE: Cardinal;
  lpBuffer: _SERVICE_STATUS_PROCESS;
  cbBufSize: DWORD;
  pcbBytesNeeded: LPDWORD;
begin
  //open the service manager  (defined in WinSvc)
  schm := OpenSCManager(PChar(sMachine), nil, SC_MANAGER_CONNECT);
  //set the status type to SC_STATUS_PROCESS_INFO
  //this is currently the only value supported
  SC_STATUS_TYPE := $00000000;
  //set the buffer size to the size of the record
  cbBufSize := sizeof(_SERVICE_STATUS_PROCESS);
  if (schm>0) then
  begin
    //grab the service handle
    schs := OpenService(schm, PChar(sService), SERVICE_QUERY_STATUS);
    if (schs>0) then
    begin
      //call the function
      QueryServiceStatusEx(
      schs,
      SC_STATUS_TYPE,
      lpBuffer,
      cbBufSize,
      pcbBytesNeeded);
      CloseServiceHandle(schs);
    end;
    CloseServiceHandle(schm);
  end;
  Result := lpBuffer.dwProcessId;
end;



end.

Please note that not all external naming and other necessities are included.

Саша Демидов

0 / 0 / 0

Регистрация: 07.02.2019

Сообщений: 32

1

Поиск процесса по имени

19.03.2019, 21:56. Показов 10383. Ответов 29

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Здравствуйте, помогите пожалуйста перевести с Lua код поиск процесса по имени, на язык программирования Delphi.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
local ProcessNames := {
 
"Tutorial-i386",
"Tutorial-x86_64.exe",
}
 
local attachToProcess := false
 
for i := 1, #ProcessNames do
if getProcessIDFromProcessName(ProcessNames[i]) ~= nil then
 
attachToProcess := true
Form1.Label1.Font.Color := 0x00FFFF80;
 
else
 
if not attachToProcess then
Form1.Label1.Font.Color := 0x000202FF;
 
end;

Добавлено через 42 минуты
Точней даже не перевезти, а исправить ошибки.



0



Flip

333 / 168 / 68

Регистрация: 25.02.2018

Сообщений: 611

20.03.2019, 14:51

2

Лучший ответ Сообщение было отмечено Саша Демидов как решение

Решение

Цитата
Сообщение от Саша Демидов
Посмотреть сообщение

перевести с Lua код поиск процесса по имени

А принципиально писать трейнеры для Сheat Engine со скриптом Lua, на Delphi, потому что:

Pascal
1
getProcessIDFromProcessName

ничто иное как функция которая используется в скрипте Lua.
Название: crystallua_logo_3.png
Просмотров: 237

Размер: 44.3 Кб
Вариантов ответа – всего два:
Вариант 1 – ДА – то Вам сюда. Это библиотека CrystalLUA – она связывает Delphi приложения и скрипты на популярном языке Lua. Внутри архива находится библиотека lua.dll и заголовок для её использования в Delphi 7. Сразу скажу, библиотека древняя на Delphi XE не завелась, вывалив кучу ошибок, править которые было лень, от слова очень, но на Delphi 7 как ни странно запустилась и отработала даже один скрипт. По утверждению её автора, цитирую: “Для
того чтобы оценить мощь и простоту библиотеки, достаточно следующего примера” ))

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
procedure TForm1.Button1Click(Sender: TObject); 
const 
  SCRIPT_STRING =  
  'Form1 {Caption="Text", Position=poScreenCenter, Color=0x007F7F7F}'; 
var 
  Lua: TLua; 
begin 
  Lua := TLua.Create; 
  Lua.RegClass(TForm1); 
  Lua.RegVariable('Form1', Form1, typeinfo(TForm1)); 
  Lua.RunScript(SCRIPT_STRING);  
  Lua.Free; 
end;

Вся мощь вышеописанного скрипта заключалась в изменении заголовка формы, её центровки на экране, и изменения её цвета. Видимо это действительно мощно, но я не оценил…
Внутри с архивом также находится справка на русском языке на 50 листах, в которой приведены использования библиотеки совместно с Delphi.

Вариант 2 – НЕТ – тогда соберите в кучу свои мысли, и желательно на общедоступном всем языке изложите смысл того, что Вы хотите. Только от Вашего более полного объяснения зависит, смогут ли Вам помочь, или нет.



1



0 / 0 / 0

Регистрация: 07.02.2019

Сообщений: 32

20.03.2019, 18:17

 [ТС]

3

Здравствуйте Ашотик2018, про библиотеку CrystalLUA я слышал, но боюсь она не будет работать на delphi rad studio 10.3 я не проверял я не знаю. Может и будет работать, дело не в этой библиотеке я хочу написать всё чисто на delphi без какой либо совместимости с другими языками программирования. Но так как я плохо шарю в delphi я прошу отредактировать этот код Lua, точней сделать такой же, но чисто на delphi.
Поиск процесса по имени, чисто на delphi.



0



Flip

333 / 168 / 68

Регистрация: 25.02.2018

Сообщений: 611

20.03.2019, 18:53

4

Лучший ответ Сообщение было отмечено Саша Демидов как решение

Решение

Цитата
Сообщение от Саша Демидов
Посмотреть сообщение

Поиск процесса по имени, чисто на delphi.

Тогда это другой разговор. Выглядеть приложение будет как то так, при загрузке программа делает так называемый “снимок” системных процессов, список которых помещает в ProcBox (ComboBox). При выборе какого либо процесса, рядом показывается его PID. Нажатием кнопки “Найти путь к процессу”, получаем полный путь к EXE-файлу выбранного процесса. При нажатии на MSGPNL (Panel) мышкой, в Explorer-e ОС откроется папка, в которой находит EXE-файл выбранного процесса.
Исходный код:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
unit Unit1;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, tlhelp32, Vcl.StdCtrls, Vcl.ExtCtrls, PsApi, ShellAPI,
  Vcl.ComCtrls;
 
type
  TForm1 = class(TForm)
    ProcName: TLabel;
    FindPathProcBtn: TButton;
    PIDBox: TEdit;
    PIDLB: TLabel;
    MSGPNL: TPanel;
    ProcBox: TComboBox;
    procedure FindPathProcBtnClick(Sender: TObject);
    procedure MSGPNLClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ProcBoxChange(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
 
implementation
 
{$R *.dfm}
 
 
type
  TMArray = array of TModuleEntry32;
 
 // Функция для получения PID из запущенного в ОС процесса
function GetPathFromPID(const PID: cardinal): string;
var
  hProcess: THandle;
  path: array[0..MAX_PATH - 1] of char;
begin
  hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, PID);
  if hProcess <> 0 then
    try
      if GetModuleFileNameEx(hProcess, 0, path, MAX_PATH) = 0 then
        result:='Null';
      result := path;
    finally
      CloseHandle(hProcess)
    end
  else
    // Если произойдёт исключение и процесс не будет найден
    // приложение предупредит об этом
    result:='Процесс с указанным PID в системе не запущен';
end;
 
   // Выводим путь к запущенному процессу на информационную панель
procedure TForm1.FindPathProcBtnClick(Sender: TObject);
begin
  MSGPNL.Caption:= GetPathFromPID(StrToInt(PIDBox.text));
end;
 
   // Процедура отображения PID выбранного процесса,
   // из списка запущенных в системе на информационной панели
procedure TForm1.ProcBoxChange(Sender: TObject);
 var
  hSnap:THandle;
  pe:TProcessEntry32;
begin
 pe.dwSize:=SizeOf(pe);
 hSnap:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
  If Process32First(hSnap,pe) then
    While Process32Next(hSnap,pe) do
      if ExtractFileName(pe.szExeFile)=(ProcBox.text) then PIDBox.text:=(IntToStr(pe.th32ProcessID));
        // Меняем цвет информационной панель на зеленый
        MSGPNL.Font.Color:= clGreen;
        // Выводим информационное сообщение о PID выбранного процесса на панель
        MSGPNL.Caption:=('PID запущенного процесса ' + (ProcBox.text) +' - ' + (PIDBox.text));
end;
 
  //Процедура получения списка запущенных в ОС процессов и загрузка их
  //ProcBox, в котором их можно будет выбирать
procedure TForm1.FormCreate(Sender: TObject);
  var
  hSnap :THandle;
  pe:TProcessEntry32;
begin
  pe.dwSize:=SizeOf(pe);
  hSnap:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
  if Process32First(hSnap,pe) then
    repeat
      ProcBox.Items.Add(pe.szExeFile);
    until not(Process32Next(hSnap,pe));
    // Выводим первый индекс из списка полученных процессов в ProcBox
      ProcBox.ItemIndex:= 1 ;
end;
 
  // Процедура для открытия папки с EXE-файлом выбранного в ProcBox процесса
procedure TForm1.MSGPNLClick(Sender: TObject);
var
Dir, Path : String;
  begin
  Path := MSGPNL.Caption; //полный путь к файлу
  Dir := ExtractFilePath(Path);//путь к папке
  ShellExecute(Handle, 'open', PWideChar(Dir), nil, nil, SW_SHOWNORMAL); //открываем папку
end;
 
end.

Выглядит как то так:

Поиск процесса по имени

Проект – PID_Proc.7z- Delphi XE7



2



0 / 0 / 0

Регистрация: 07.02.2019

Сообщений: 32

20.03.2019, 19:19

 [ТС]

5

Ашотик2018 спасибо тебе конечно, но ты бы не мог помочь именно с моим кодом, просто сделать точно Токой же но на delphi. Я видел пример твоего кода, выбор процесса через ComboBox, когда искал в интернете как сделать поиск процесса по имени на delphi, но своего примера я не нашёл. Возможно ли код

поиск процесса по имени

который я выложил, сделать под delphi.



0



333 / 168 / 68

Регистрация: 25.02.2018

Сообщений: 611

20.03.2019, 19:29

6

Лучший ответ Сообщение было отмечено Саша Демидов как решение

Решение

Цитата
Сообщение от Саша Демидов
Посмотреть сообщение

поиск процесса по имени

Что в твоём понятии ИМЯ процесса?
Поскольку букварь гласит следующее – ProcessName – свойство содержит имя исполняемого файла, например Outlook, который не поддерживает расширения .exe или путь. Это полезно для получения и обработки всех процессов, которые связаны с тем же исполняемым файлом.

PID – Идентификатор процесса (англ. Process Identifier, PID) — уникальный номер (идентификатор) процесса в многозадачной операционной системе (ОС). В ОС семейства Windows pid хранится в переменной целочисленного типа.



1



Саша Демидов

0 / 0 / 0

Регистрация: 07.02.2019

Сообщений: 32

20.03.2019, 23:23

 [ТС]

7

Вот так у меня шел код. Где я здесь ошибся, почему он не работает на delphi.
Код правильный где я ошибся, подправьте пожалуйста код чтобы он заработал на delphi.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
procedure TForm1.Timer1Timer(Sender: TObject);
begin
local ProcessNames := {
 
"Tutorial-i386",
"Tutorial-x86_64.exe",
}
 
local attachToProcess := false
 
for i := 1, #ProcessNames do
if getProcessIDFromProcessName(ProcessNames[i]) ~= nil then
 
attachToProcess := true
Form1.Label1.Font.Color := 0x00FFFF80;
 
else
 
if not attachToProcess then
Form1.Label1.Font.Color := 0x000202FF;
 
end;

Добавлено через 1 час 22 минуты
Почему delphi

local ProcessNames

пишет как ошибку я не понял.

Добавлено через 2 часа 12 минут
Почему выдаёт ошибку, local ProcessNames может кто ни будь скажет.
И здесь выдаёт ошибку, local attachToProcess := false код же правильный.
Пожалуйста помогите.



0



Модератор

8442 / 5632 / 2287

Регистрация: 21.01.2014

Сообщений: 24,175

Записей в блоге: 3

21.03.2019, 07:59

8

Цитата
Сообщение от Саша Демидов
Посмотреть сообщение

код же правильный

Это кто Вам вообще такое сказал? Это не код, это бред сивой кобылы под тяжелой наркотой… Вот на вскидку косяки с точки зрения Дельфи
1. Что такое local и что такое ProcessNames? Такая запись даже близко не похожа на дельфийскую конструкцию. Если на то пошло – это больше похоже на С-шное объявление переменной ProcessNames типа local, но такого типа в Дельфи нет.
2. Что Вы присваиваете в качестве значения в строке 3 – комментарий?
3. Строка 9. Аналогично п. 1, только переменная другая
4. Что это за организация цикла такая в строке 11?
5. ~= – нет такой операции в Дельфи!!!
6. В строках 13 и 16 пропущены открывающая и закрывающая операторные скобки…
7. HEX-числа в Дельфи записываются как $00FFFF80. То, что у Вас – С-шная запись…

А так, да, конечно, код правильный…



1



Flip

333 / 168 / 68

Регистрация: 25.02.2018

Сообщений: 611

21.03.2019, 09:06

9

Пришлось почитать вчера по этому поводу много разной инфы. Тут суть проблемы такова. Код, который написан ТС, как и говорил в посте 2, это смесь с бульдога с носорогом. Программы Cheat Engine существует две редакции: первая создана в среде разработки Delphi, вторая в среде Lazarus. Первая редакция написана специально для 32-х разрядной версии Windows XP. А Cheat Engine Lazarus предназначен для 32-х и 64-битных версий Windows. Сама программа Cheat Engine написана на Object Pascal за исключением модуля ядра, который написан на C.
Для расширения её возможностей и создания скриптов была написана библиотека Crysta LUA, о которой говорил уже выше.
Нижеуказанный код:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
procedure TForm1.Timer1Timer(Sender: TObject);
begin
   local ProcessNames := { "Tutorial-i386", "Tutorial-x86_64.exe", }
      local attachToProcess := false
            for i := 1, #ProcessNames do
                  if getProcessIDFromProcessName(ProcessNames[i]) ~= nil then
                        attachToProcess := true
                        Form1.Label1.Font.Color := 0x00FFFF80;
                        else
                  if not attachToProcess then
                        Form1.Label1.Font.Color := 0x000202FF;
 end;

будет (и работает) в Cheat Engine и правильный, НО НЕ ДЛЯ DELPHI, а для связки LUA + Cheat Engine.
В коде идет аттач к выбранному процессу и оповещение пользователя, о состоянии попытки присоедениться к выбранному процессу из вне.
Запись

Delphi
1
local ProcessNames := { "Tutorial-i386", "Tutorial-x86_64.exe", }

Является параметром функции getProcessIDFromProcessName, которую и использует как раз та самая библиотека LUA, да и по синтаксису это точно она, там автор его видит по своему, поэтому где в Delphi двоеточие у него просто точки, запятые, фигурные скобки, ну вообщем не суть. Так что, то что похоже и где-то работает правильно, не всегда является правильным для другой среды.
Что же касается самой сути кода на Delphi, то описание подобного можно найти в Help-e здесь и здесь.



1



0 / 0 / 0

Регистрация: 07.02.2019

Сообщений: 32

22.03.2019, 23:03

 [ТС]

10

Да я понял что ошибку сделал, но не пойму как мене сделать без выбора процесса через ComboBoxEx1 я хочу в писать Имя процесс в ручную тот который мене надо, и через таймер чтобы это процесс запускался при нахождении процесса, твой код делает снимок всех процессов, а мене так не надо. Прошу помочь, так как в Delphi я плохо разбираюсь.



0



333 / 168 / 68

Регистрация: 25.02.2018

Сообщений: 611

22.03.2019, 23:19

11

Саша Демидов, Давай разберёмся предметно, что ты хочешь видеть в итоге. Это должно быть приложение, которое запускает некую программу, если её название появляется в поле ввода. Если нет, то приложение грубо говоря, висит и курит. Имя процесса в поле ввода, ты будешь заносить ручками (например твой Tutorial-i386.exe), и по таймеру проверять, есть ли в поле ввода этот процесс или нет. Правильно я тебя понял?



1



0 / 0 / 0

Регистрация: 07.02.2019

Сообщений: 32

22.03.2019, 23:41

 [ТС]

12

Тот код который я выложил на Lua работал таким образом,вписываешь имя процесса в ProcessName := { “Tutorial-i386.exe”,} после запускаешь программу Tutorial-i386.exe есть такая в программе Cheat Engine, после нахождения процесса Tutorial-i386.exe имя этого процесса выводилось в Edit1 и показывало имя процесса в Edit1 и менялся цвет при нахождении процесса Tutorial-i386.exe. вот как я хотел сделать на Delphi но знания не позволяют сделать это.

Добавлено через 7 минут
Твой код который ты выложил Ашотик2018 хороший, но я не знаю как убрать ComboBoxEx1 и кнопку Button2 и сделать это всё через таймер c ручным вписыванием имя процесса, на то имя которое надо например Tutorial-i386.exe.



0



333 / 168 / 68

Регистрация: 25.02.2018

Сообщений: 611

22.03.2019, 23:58

13

Цитата
Сообщение от Саша Демидов
Посмотреть сообщение

и менялся цвет

Цвет чего должен меняться? Формы, Edit-a или может ещё чего.

Добавлено через 2 минуты

Цитата
Сообщение от Саша Демидов
Посмотреть сообщение

и сделать это всё через таймер c ручным вписыванием имя процесса

А зачем таймер, если ты процесс РУКАМИ вводишь и знаешь что он уже там есть! Что проверять должен таймер??



1



Саша Демидов

0 / 0 / 0

Регистрация: 07.02.2019

Сообщений: 32

23.03.2019, 00:59

 [ТС]

14

Менялся цвет имя процесса в Edit1 имя этого процесса Tutorial-i386.exe.
Таймер нужен чтобы при запуске программы Tutorial-i386.exe находилось имя этой программы то есть её процесс имя этого процесса Tutorial-i386.exe и выводилось в Edit1. При закрытии процесса Tutorial-i386.exe процесс в Edit1 исчезал. В мой код можно было вписать несколько процессов, например запускаешь программу Tutorial-i386.exe процесс этой программы c помощью таймера находился и выводится в Edit1 захотел закрыл программу Tutorial-x86.exe,
и открыл Tutorial-x86_64.exe и имя этого процесса Tutorial-x86_64.exe, выводилась на Edit1.

Добавлено через 34 минуты
Вот как выглядит код, на Lua полный.
И как он работал.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[B]function CETimer1Timer(sender) -- Этот таймер находил открытый процесс Tutorial-i386.exe этой программы Tutorial-i386
 
local ProcessNames = {
 
"Tutorial-i386.exe", -------вот это имя процесса которое находилось при открытии программы Tutorial-i386
"Tutorial-x86_64.exe",  ------ или вот это имя процесса находилась при открытии этой программы Tutorial-x86_64
}
local attachToProcess = false
 
for i = 1, #ProcessNames do
if getProcessIDFromProcessName(ProcessNames[i]) ~= nil then
 
attachToProcess = true
UDF1.CELabel1.Font.Color = 0x00FFFF80----меняет цвет имя процесса вEdit1
UDF1.CEEdit1.Text = ProcessNames[i] ---выводит имя найденного процесса открытой программы в Edit1 и показывает его.
 
else
 
if not attachToProcess then
UDF1.CELabel1.Font.Color = 0x000202FF -- меняет цвет имя процесса в Edit1 при закрытии программы с её процессом
UDF1.CEEdi1.Text = ""  ------- При закрытии процесса Tutorial-i386.exe имя этого процесса исчезало из Edit1
 
end[/B]

Добавлено через 12 минут
Вот так и работал код.



0



Flip

333 / 168 / 68

Регистрация: 25.02.2018

Сообщений: 611

23.03.2019, 03:29

15

Если все правильно понял, то:
Приложение будет выглядеть следующим образом (сделал только для Tutorial-i386.exe). На кнопке “Запустить” висит таймер, который с интервалом, указанным в SpinEdit (время указывается в миллисекундах), начинает проверять запущен в ОС процесс с именем Tutorial-i386.exe или нет. Если процесс запущен, то выводит его название цветом морской волны в Edit1? если нет то висит и ждёт запуска процесса, при этом таймер бороздит просторы в поисках процесса, в списке запущенных в ОС. Нажимая на кнопку “Остановить” таймер прекращает поиск заданного процесса.
Исходный код:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, tlhelp32, ExtCtrls, StdCtrls, Spin;
 
type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Timer1: TTimer;
    SpinEdit1: TSpinEdit;
    Button1: TButton;
    Label2: TLabel;
    Button2: TButton;
    Button3: TButton;
    Label1: TLabel;
    procedure Timer1Timer(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
// Функция поиска запущенного процесса
function IsRunning(sName: string): boolean;
var
  han: THandle;
  ProcStruct: PROCESSENTRY32;
  sID: string;
begin
  Result := false;
 
  han := CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
  if han = 0 then
    exit;
 
  ProcStruct.dwSize := sizeof(PROCESSENTRY32);
  if Process32First(han, ProcStruct) then
  begin
    repeat
      sID := ExtractFileName(ProcStruct.szExeFile);
 
      if uppercase(copy(sID, 1, length(sName))) = uppercase(sName) then
      begin
 
        Result := true;
        Break;
      end;
    until not Process32Next(han, ProcStruct);
  end;
 
  CloseHandle(han);
end;
 
// Таймер для проверки запущен процесс или нет
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  // Проверяем запущен ли процесс
  timer1.Interval := StrToInt(SpinEdit1.Text);
  // Если запущен то:
  if IsRunning('Tutorial-i386.exe') then
  begin
    //то выводим имя процесса
    Edit1.Text := ('Tutorial-i386.exe');
    //делаем его цветом морской волны (близкий значению цвета 0x00FFFF80, указанному Вами в скрипте)
    Edit1.Font.Color := clAqua;
  end
  // Если не запущен то:
  else
  begin
    //делаем его красным цветом (близкий значению цвета 0x000202FF, указанному Вами в скрипте)
    //бред полный, ТАК ДЕЛАТЬ НЕ НУЖНО!!!
    Edit1.Font.Color := clRed;
    //очищаем поле где находился процесс
    Edit1.Text := ('');
  end;
 
end;
 
//Запускаем таймер
procedure TForm1.Button1Click(Sender: TObject);
begin
  timer1.Enabled := True;
end;
 
//Останавливаем таймер, очищаем Edit1
procedure TForm1.Button2Click(Sender: TObject);
begin
  timer1.Enabled := False;
  Edit1.Text := '';
end;
 
//Закрываем приложение
procedure TForm1.Button3Click(Sender: TObject);
begin
  Close;
end;
 
end.

Выглядит и работает как-то так:

Поиск процесса по имени

Проект – Ver_1.0.7z.

НО!!! У меня очень большой вопрос конечно по поводу цвета текста процесса, который не запущен. ИМХО бред полнейший и вот этот кусок кода из Вашего скрипта меня немного ввел в заблуждение:

Delphi
1
2
UDF1.CELabel1.Font.Color = 0x000202FF -- меняет цвет имя процесса в Edit1 при закрытии программы с её процессом
UDF1.CEEdi1.Text = ""  ------- При закрытии процесса Tutorial-i386.exe имя этого процесса исчезало из Edit1

Процесс Tutorial-i386.exe закрывается очень быстро даже на моей черепахе. Вопрос из прочитанного в этих двух строках напрашивается. Процесс исчезает из Edit1, там просто ничего нет!!! Зачем изменять цвет шрифта текста, которого там нет, даже визуально Вы просто видите там белое поле, без букв. А как же красный текст ??? Логики нет вообще, ну да это уже Ваше дело.
Как по мне, я бы лучше менял цвет формы, это и логично и более наглядно, то есть это можно увидеть глазами, если процесс найден, то форма цвета морской волны, если нет, то красного, так хоть что-то будет понятно. Да и если процесс не запущен, то в Edit1 можно вывести сообщение об этом. Если такой вариант все же подойдёт, то он ниже.
Исходный код:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, tlhelp32, ExtCtrls, StdCtrls, Spin;
 
type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Timer1: TTimer;
    SpinEdit1: TSpinEdit;
    Button1: TButton;
    Label2: TLabel;
    Button2: TButton;
    Button3: TButton;
    Label1: TLabel;
    procedure Timer1Timer(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
// Функция поиска запущенного процесса
function IsRunning(sName: string): boolean;
var
  han: THandle;
  ProcStruct: PROCESSENTRY32;
  sID: string;
begin
  Result := false;
 
  han := CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
  if han = 0 then
    exit;
 
  ProcStruct.dwSize := sizeof(PROCESSENTRY32);
  if Process32First(han, ProcStruct) then
  begin
    repeat
      sID := ExtractFileName(ProcStruct.szExeFile);
 
      if uppercase(copy(sID, 1, length(sName))) = uppercase(sName) then
      begin
 
        Result := true;
        Break;
      end;
    until not Process32Next(han, ProcStruct);
  end;
 
  CloseHandle(han);
end;
 
// Таймер для проверки запущен процесс или нет
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  // Проверяем запущен ли процесс
  timer1.Interval := StrToInt(SpinEdit1.Text);
  // Если запущен то:
  if IsRunning('Tutorial-i386.exe') then
  begin
    //то выводим имя процесса
    Edit1.Text := ('Tutorial-i386.exe');
    //делаем форму цветом морской волны
    Form1.Color := clAqua;
  end
  // Если не запущен то:
  else
  begin
     //Сообщаем о том что процесс не запущен в ОС
     Edit1.Text := ('Процесс не запущен!');
     //делаем форму красным цветом
     Form1.Color := clRed;
  end;
 
end;
 
//Запускаем таймер
procedure TForm1.Button1Click(Sender: TObject);
begin
  timer1.Enabled := True;
end;
 
//Останавливаем таймер, очищаем Edit1
procedure TForm1.Button2Click(Sender: TObject);
begin
  timer1.Enabled := False;
  Edit1.Text := '';
end;
 
//Закрываем приложение
procedure TForm1.Button3Click(Sender: TObject);
begin
  Close;
end;
 
end.

Выглядит и работает как-то так (всё же получше чем первый вариант):

Поиск процесса по имени

Проект – Ver_1.1.7z.

Enjoy The game!



1



Саша Демидов

0 / 0 / 0

Регистрация: 07.02.2019

Сообщений: 32

23.03.2019, 13:27

 [ТС]

16

Привет Ашотик2018.

Спасибо за код

.
Я понял этот код, он ищет открытый процесс, без этого кода работать не будет.
Скажи пожалуйста вот этот код ошибку выдаёт при сборки.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function IsRunning(sName: string): boolean;
var
  han: THandle;
  ProcStruct: PROCESSENTRY32;
  sID: string;
begin
  Result := false;
 
  han := CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
  if han = 0 then
    exit;
 
  ProcStruct.dwSize := sizeof(PROCESSENTRY32);
  if Process32First(han, ProcStruct) then
  begin
    repeat
      sID := ExtractFileName(ProcStruct.szExeFile);
 
      if uppercase(copy(sID, 1, length(sName))) = uppercase(sName) then
      begin
 
        Result := true;
        Break;
      end;
    until not Process32Next(han, ProcStruct);
  end;
 
  CloseHandle(han);
end;

Добавлено через 14 минут
Я тебе сейчас готовы скрипт на Lua дам Ашотик2018, и ты поймёшь как этот код работал.



0



0 / 0 / 0

Регистрация: 07.02.2019

Сообщений: 32

23.03.2019, 13:51

 [ТС]

17

Вот Ашотик2018 скачай и запусти, на Cheat Engine и ты всё поймёшь как мене на добыло сделать на Delphi.



0



0 / 0 / 0

Регистрация: 07.02.2019

Сообщений: 32

23.03.2019, 14:05

 [ТС]

18

Вот перезолил по новой скачай.

Модератора прошу удалить, 17 и 18 сообщения.



0



0 / 0 / 0

Регистрация: 07.02.2019

Сообщений: 32

23.03.2019, 14:08

 [ТС]

19

Вот перезолил скачай по новой.



0



Flip

333 / 168 / 68

Регистрация: 25.02.2018

Сообщений: 611

23.03.2019, 14:59

20

Цитата
Сообщение от Саша Демидов
Посмотреть сообщение

Скажи пожалуйста вот этот код ошибку выдаёт при сборки.

Не может такого быть!!! Я же приложил исходники, готовые скомпилированные проекты, и даже показал на скринах как все работает. Где он не работает???? У меня вопрос, где или в чем ты её собираешь, просто дабы убить вот эти все высказывания типа “У меня не работает” специально писал на Delphi7, при этом не использовал никаких дополнительных сторонних компонентов и библиотек, единственно подключал в uses модуль tlhelp32.

Delphi
1
2
3
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, [B]tlhelp32[/B], ExtCtrls, StdCtrls, Spin;

Теперь о скрипте, который в архиве. Сам по себе скрипт, а именно файл ПОИСК ПРОЦЕССА ПО ИМЕНИ НА Lua.CT это просто текстовый документ, который что есть что его нет, толку никакого. Чтобы он работал нужна еще форма, на которую помещены компоненты, с выставленными свойствами. В Вашем случае это должен быть файл с названием UDF1.frm. А так скрипт сам по себе не актуален.

Поиск процесса по имени

Чтобы писать что либо, надо иметь хотя бы некое представление о том, с чем имеешь дело. Я до Вашего топика в жизни никогда и не знал что есть LUA. Пару дней посидев и почитав в свободное время теперь имею представление. Попробуйте и вот ещё. Исходя из того что написано в Вашем скрипте, это ничто иное, как простой индикатор запуска процесса, в Вашем случае Tutorial-i386.exe.
То что Вы хотели, я Вам описал по буквам тут, больше соображений у меня нет.



1



    msm.ru

    Нравится ресурс?

    Помоги проекту!

    Пожалуйста, выделяйте текст программы тегом [сode=pas] … [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.


    Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
    1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
    2. Как “свернуть” программу в трей.
    3. Как “скрыться” от Ctrl + Alt + Del (заблокировать их и т.п.)
    4. Как прочитать список файлов, поддиректорий в директории?
    5. Как запустить программу/файл?
    … (продолжение следует) …


    Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
    Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


    Внимание
    Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
    Повторная попытка – 60 дней. Последующие попытки бан.
    Мат в разделе – бан на три месяца…

    >
    Найти окно, принадлежащее процессу

    • Подписаться на тему
    • Сообщить другу
    • Скачать/распечатать тему



    Сообщ.
    #1

    ,
    19.02.03, 17:34

      Как по известному идентификатору процесса узнать хэндл его окна?
      Допустим, мы сами запускаем ShellExecute, и получаем ID процесса:

      ProcessID:HInstance;
      WindowID:HWnd;

      ProcessID := ShellExecute(Handle,’open’,PChar(PathToMyCoolProg),PChar(ParameterString),PChar(CurrentDirectory),SW_SHOW);

      Как теперь найти окно данного процесса?
      Что-нибудь типа

        WindowID:= ?FindProcessWindowHandle?(ProcessID);

      Ранее было предложено решение после запуска процесса
      сделать Sleep на пару-тройку секунд, а затем найти хэндл самого верхнего окна.

             Sleep(3000);
             WindowID := GetForeGroundWindow;

      Но проблема в том, что за эти 2-3 секунды наверх может всплыть совсем другое окно, например аськино сообщение, или еще что-нибудь… И в результате мы “схватим” совершенно чужой хэндл!
      А нужно найти именно то окно, которое принадлежит конкретному процессу…
      Есть ли другие решения для этой задачки?


      Song



      Сообщ.
      #2

      ,
      19.02.03, 18:56

        :) я когда писал, об этом думал, но сам помнишь, времени не было.
        А жестокая реальность такова: ShellExecute() для этого не подходит. Надо либо ShellExecuteEx() либо CreateProcess(). Оба возвращают в своей структуре дискриптор запущенного процесса. Можно также ещё припахать WaitForInputIdle() – ждёт пока программа не получит статуса “активности”.

        Сообщение отредактировано: Song – 19.02.03, 18:57

        Guru

        vot



        Сообщ.
        #3

        ,
        21.02.03, 09:50

          Думал.
          Много читал.
          Ничерта не понял :)

          Можно примерчик? Или ссылочку…


          Song



          Сообщ.
          #4

          ,
          21.02.03, 12:41

            Procedure CrProcess(FName,S:String);
            Var SeInfo:TShellExecuteInfo;
            Begin
            FillChar(SEInfo,SizeOf(SEInfo),0);
            With SEInfo Do
             Begin
              cbSize:=SizeOf(TShellExecuteInfo);
              fmask:=SEE_MASK_NOCLOSEPROCESS;
              Wnd:=Application.Handle;
              lpFile:=PChar(FName);
              lpParameters:=PChar(S);
              lpDirectory:=nil;
              nShow:=SW_HIDE;
             End;
            ShellExecuteEx(@SEInfo);
            End;

            После запуска процесса (ShellExecuteEx), дискриптор запущенного процесса будет в SEInfo.hProcess

            Guru

            vot



            Сообщ.
            #5

            ,
            21.02.03, 13:35

              Опять не понял…
              Ну, получили мы идентификатор запущенного процесса в SEInfo.hProcess,
              и… куда его теперь засунуть?
              Надо-то получить хэндл окна этого процесса!


              Song



              Сообщ.
              #6

              ,
              21.02.03, 14:35

                Перебрать… есть GetWindowThreadProcessID(), она требует hwnd, этот hwnd можно получить перебором по всем окнам через EnumWindows(), если ID будут одинаковые значит это то окно.

                Guru

                vot



                Сообщ.
                #7

                ,
                22.02.03, 08:58

                  Неужели не существует более прямого метода???


                  Song



                  Сообщ.
                  #8

                  ,
                  22.02.03, 09:48

                    Нет, дело в том, что по окну можно найти процесс, а обратное не верно т.к. процесс (поток) может содержать сколько угодно окон, также как и не содержать их вообще.

                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)

                    0 пользователей:

                    • Предыдущая тема
                    • Delphi: Общие вопросы
                    • Следующая тема

                    Рейтинг@Mail.ru

                    [ Script execution time: 0,0274 ]   [ 16 queries used ]   [ Generated: 23.05.23, 19:05 GMT ]  

                    Using Delphi (windows app) i want to get list of other applications running currently. Here How to check if a process is running using Delphi? i’ve found great tutorial about geting filenames/names of running application, however it gives names only process name (for example NOTEPAD.EXE). I’ve used naturally part with

                    UpperCase(ExtractFileName(FProcessEntry32.szExeFile))

                    and

                    UpperCase(ExtractFilePath(FProcessEntry32.szExeFile))

                    and just

                    UpperCase(FProcessEntry32.szExeFile)

                    but obviously FProcessEntry32.szExeFile does not have a path to file/process

                    Is there a simply way of getting list with paths? Here’s How to get the list of running processes including full file path? solution with JclSysInfo library, but i cant use it in place of work in project.

                    I looked at what I could in Google and what I found usually concerned just the application that is running or the application that is active, but I can’t just find a list of all running applications. Maybe i’m missing something obvious?

                    I’m not looking for any complex procedures, I’m not much interested in process parrent, or if there is no access to the process path, I don’t have it and don’t bother.

                    Any simple hint?

                    OK, due to helpfull comment from @TLama i’ve combined topics above to take name and path of process:

                    function processExists(exeFileName: string): Boolean;
                    var
                      ContinueLoopP, ContinueLoopM: BOOL;
                      FSnapshotHandle1, FSnapshotHandle2: THandle;
                      FProcessEntry32: TProcessEntry32;
                      FMODULEENTRY32: TMODULEENTRY32;
                    begin
                      FSnapshotHandle1 := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
                      FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
                      FMODULEENTRY32.dwSize := SizeOf(FMODULEENTRY32);
                      ContinueLoopP := Process32First(FSnapshotHandle1, FProcessEntry32);
                      ContinueLoopM := Module32First(FSnapshotHandle2, FMODULEENTRY32);
                      Result := False;
                      while Integer(ContinueLoopP) <> 0 do
                      begin
                        if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
                          UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) =
                          UpperCase(ExeFileName))) then
                          Result := True;
                        ShowMessage(FMODULEENTRY32.szExePath + FProcessEntry32.szExeFile);
                        ContinueLoopP := Process32Next(FSnapshotHandle1, FProcessEntry32);
                        ContinueLoopM := Module32Next(FSnapshotHandle2, FMODULEENTRY32);
                      end;
                      CloseHandle(FSnapshotHandle1);
                      CloseHandle(FSnapshotHandle2);
                    end;
                    

                    But still FProcessEntry32.szExeFile returns empty string. What i’m doing wrong? Thank You in advance.

                    1

                    2

                    3

                    4

                    5

                    6

                    7

                    8

                    9

                    10

                    11

                    12

                    13

                    14

                    15

                    16

                    17

                    18

                    19

                    20

                    21

                    22

                    23

                    24

                    25

                    26

                    27

                    28

                    29

                    30

                    31

                    32

                    33

                    34

                    35

                    36

                    37

                    38

                    39

                    40

                    41

                    42

                    43

                    44

                    45

                    46

                    47

                    48

                    49

                    50

                    51

                    52

                    53

                    54

                    55

                    56

                    57

                    58

                    59

                    60

                    61

                    62

                    63

                    64

                    65

                    66

                    67

                    68

                    69

                    70

                    71

                    72

                    73

                    74

                    75

                    76

                    77

                    78

                    79

                    80

                    81

                    82

                    83

                    84

                    85

                    86

                    87

                    88

                    89

                    90

                    91

                    92

                    93

                    94

                    95

                    96

                    97

                    98

                    99

                    100

                    101

                    102

                    103

                    104

                    105

                    106

                    107

                    108

                    109

                    110

                    111

                    112

                    113

                    114

                    115

                    116

                    117

                    118

                    119

                    120

                    121

                    122

                    123

                    124

                    125

                    126

                    127

                    128

                    129

                    130

                    131

                    132

                    133

                    134

                    135

                    136

                    137

                    138

                    139

                    140

                    141

                    142

                    143

                    144

                    145

                    146

                    147

                    148

                    149

                    150

                    151

                    152

                    153

                    154

                    155

                    156

                    157

                    158

                    159

                    160

                    161

                    162

                    163

                    164

                    165

                    166

                    167

                    168

                    169

                    170

                    171

                    172

                    173

                    174

                    175

                    176

                    177

                    178

                    179

                    180

                    181

                    unit Unit1;

                    interface

                    uses

                    Windows, Messages, SysUtils, Variants, Classes, Graphics,

                    Controls, Forms, Dialogs, StdCtrls,PSAPI, TlHelp32;

                    type

                    TForm1 = class(TForm)

                    Button1: TButton;

                    Memo1: TMemo;

                    Button2: TButton;

                    procedure Button1Click(Sender: TObject);

                    private

                    { Private declarations }

                    public

                    { Public declarations }

                    end;

                    var

                    Form1: TForm1;

                    implementation

                    {$R *.dfm}

                    function GetProcessList(): TStrings;

                    var

                    eP: TProcessEntry32;

                    hP, snap: THandle; //дескрипторы процесса и снимка

                    hM: hmodule; //дескриптор модуля

                    prcs: array[0..$FFF] of dword; //массив для хранения

                    // дескрипторов процессов

                    cP, cM: cardinal; //количество процессов

                    i: integer;

                    NameProc: array[0..max_path] of char; //имя модуля

                    lP: TStrings;

                    begin

                    lP:=TStringList.Create;

                    lP.Clear;

                    //проверяем версию винды

                    if Win32Platform = VER_PLATFORM_WIN32_WINDOWS then

                    begin //если это Win9x

                    //инициализируем переменные

                    snap := CreateToolhelp32Snapshot(th32cs_snapprocess, 0);

                    if integer(snap) = 1 then

                    begin

                    exit;

                    end

                    else

                    begin

                    eP.dwSize := sizeof(eP);

                    //для Win9x получение списка процессов выполняется по

                    //аналогии с поиском файлов

                    //вызываем функцию для получения первого процесса

                    if Process32First(snap, eP) then

                    //а далее в цикле пока еще есть процессы получаем следующий

                    repeat

                    lP.Add(string(eP.szExeFile));//получаем имя процесса

                    until not Process32Next(snap, eP);

                    end;

                    end

                    else

                    begin //Если WinNT/2000/XP

                    //то в этом случае мы пользуемся Api-функцией перечисления

                    // запущенных процессов

                    //которая заполняет нам наши переменные

                    if not EnumProcesses(@prcs, sizeof(prcs), cP) then

                    begin

                    exit;

                    end;

                    //и далее для каждого дескриптора процесса получаем о нем

                    // информацию

                    for i := 0 to cP div 4 1 do

                    begin

                    hP := OpenProcess(PROCESS_QUERY_INFORMATION or

                    PROCESS_VM_READ,

                    false, prcs[i]);

                    if hP > 0 then

                    begin

                    EnumProcessModules(hP, @hM, 4, cM);

                    GetModuleFileNameEx(hP, hM, NameProc, sizeof(NameProc));

                    lP.Add(ExtractFileName(string(NameProc))); //если вы хотите

                    // получить только имена процессов

                    // lP.Add(string(NameProc)); //если вы хотите получить

                    // имена процессов вместе c путем

                    CloseHandle(hP);

                    end;

                    end;

                    end;

                    GetProcessList:=lP; //возвращаем полученный список

                    end;

                    procedure TForm1.Button1Click(Sender: TObject);

                    begin

                    memo1.Lines:=GetProcessList;

                    end;

                    end.

                    Добавить комментарий