We connect the module in uses:

tlHelp32; 

Function by definition process:

 function FindTask(ExeFileName: string): Integer; var ContinueLoop: LongBool; hSnapshot: THandle; PE32: TProcessEntry32; begin Result := 0; hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); PE32.dwSize :=SizeOf(TProcessEntry32); ContinueLoop := Process32First(hSnapshot, PE32); while Integer(ContinueLoop) <> 0 do begin if ((UpperCase(ExtractFileName(PE32.szExeFile)) = UpperCase(ExeFileName)) or (UpperCase(PE32.szExeFile) = UpperCase(ExeFileName))) then Result := 1; ContinueLoop :=Process32Next(hSnapshot, PE32); end; CloseHandle(hSnapshot); end; 

Well, we connect the function to the button:

  procedure TForm1.Button1Click(Sender: TObject); begin if FindTask('Process.exe') = 1 then ShowMessage('Process.exe - запущен!') else ShowMessage('Process.exe - не запущен!'); end; 

How to fix this function, so that after pressing the button, check - whether the process was started ( Process.exe ) or not - was carried out after 3 seconds and then every 5 seconds? That is: pressing the button, it takes the first 3 seconds , the timer turns on and then the test is carried out every 5 seconds.

  • one
    Tatiana, do you need exactly 3 and 5 seconds, respectively, or is a small error allowed? - Dima
  • @Dima, Not necessarily, it is possible and with an error, - Tatiana

1 answer 1

Tatiana, I can offer this option.

Find the System tab in the component palette. Open it, look for TTimer in the list of components. Add it to the form, in the object inspector we find the Interval property. It is able to take the value of the delay in milliseconds. To set the delay to 5 seconds, you must assign this property a value of 5000 (1 second = 1000 milliseconds).

Then double-click on the TTimer component on the form and write a code handler - that is, your search function of the process.

Then go to the handler button to start the search process.
Double click on the button, we write the following code:

 procedure TForm1.aButton1Click(Sender: TObject); var Interval: DWord; StartTime: DWord; StopTime: DWord; begin // Задаем интервал для отсчета 3-х секунд Interval := 3000; // Отсчитываем эти секунды... StartTime := GetTickCount; repeat StopTime := GetTickCount; until (StopTime - StartTime) >= Interval; // Секунды отсчитаны успешно, переходим к первичному поиску процесса if FindTask('Process.exe') = 1 then ShowMessage('Process.exe - запущен!') else ShowMessage('Process.exe - не запущен!'); // Нашли/не нашли, переходим к периодическому поиску процесса, // для чего запускаем предварительно настроенный таймер Timer1.Enabled := true; end; 

Help for the GetTickCount function tells us that

This is a trickle-down of the system of the timer, which has been limited to 10 milliseconds to 16 milliseconds.

In other words, the accuracy of the value returned by the function depends on the system timer and ranges from 10 to 16 milliseconds. In this regard, there is no guarantee that the first search process will be performed exactly after 3 seconds. This is what I had in mind when I asked about the permissibility of error.

The same with the TTimer component. For his work, he (the component) creates an invisible window that checks for the presence of a WM_TIMER message in the message queue of this window. Due to the fact that, according to help

The WM_TIMER message is a low-priority message.

Since this message has a low priority , it becomes absolutely impossible to expect an exact response timer in exactly 5 seconds, since the messages with high priority will be processed first, which guarantees a certain delay (minimum, but still).

Thus, the error in the countdown will be present, but it will not affect the solution of your problem.

Information sources:
Gettickcount
WM_TIMER message

  • 2
    Great solution, now I will understand this code too :). Thank you - Dmitry, and many more people of this wonderful community, for helping with various tasks! - Tatiana
  • In fact, everything is simpler: we put this check into a timer, set it to an interval of 3 seconds. By pressing the button, we start the timer. In the Timer1OnTimer () handler, the first line sets the timer to an interval of 5 seconds. Everything. At the same time, the form will not "hang" for 3 seconds when pressing the button. - Alekcvp
  • @Alekcvp, and we get a double call to SetTimer and KillTimer - when the timer starts and when a new interval is assigned. Another thing: if the Enabled := true timer is turned on, the system will not create a timer (lack of resources), then there is a risk that the timer will not work even once , but this is not good. In the condition of the question it is said: pressing the button - checking the process - starting the timer with a periodic check of the process. And in general - it is a bad form: change the timer interval from the timer execution handler. This is my opinion, but you are certainly free to disagree and give your answer;) - Dima
  • @Dima, well, in my personal opinion, the double call of SetTimer and KillTimer is nothing compared to the interface hanging for 3 seconds (when the button is pressed). And at the same time, see how much CPU time your application will consume in those 3 seconds. And if the system is so bad that there are not enough resources even for a timer, then the timer that did not work will be your smallest problem. We are not talking about Windows 95. - Alekcvp
  • @Alekcvp, you can argue long about the cycles, calls, CPU consumption. BUT. I fulfilled the condition of the question - the timer starts after 3 seconds . Concerning a freezing of the form - it is possible to resort to Application.ProcessMessages . Application.ProcessMessages . Yes, not the smoothest option, but still for the 3-second delay fits perfectly. And again: to modify an object from the handler of the same object — moveton . - Dima