Home > Mobile >  Keep trying a command until it returns "True" and then execute another
Keep trying a command until it returns "True" and then execute another

Time:01-06

I'm trying to make a script to check the processor usage for a specific process every 10 seconds, and when the usage is less than 2% I want another 2 commands to be executed.

The purpose is to know when the program has finished processing the requests, in order to release the execution of the other commands.

I created this script to check the processor usage by this application:

SET ProcessorUsage = wmic path Win32_PerfFormattedData_PerfProc_Process get Name,PercentProcessorTime | findstr /i /c:RenderQuery

%ProcessorUsage%

And these are the commands I want to be executed when the processor usage of the RenderQuery application is less than 2%:

for /f "delims=" %%X in ('dir /s/b/ad Proxy') do for /f "delims=" %%Y in ('dir /s/b/a-d "%%X"') do move "%%Y" ".\03. Proxy"

for /f "delims=" %%i in ('dir /s/b/ad Proxy') do rd "%%i"

I tried to create a script that way here:

SET ProcessorUsage = wmic path Win32_PerfFormattedData_PerfProc_Process get Name,PercentProcessorTime | findstr /i /c:RenderQuery
:Loop
IF %ProcessorUsage% LSS 2 (
(for /f "delims=" %%X in ('dir /s/b/ad Proxy') do for /f "delims=" %%Y in ('dir /s/b/a-d "%%X"') do move "%%Y" ".\03. Proxy") && (for /f "delims=" %%i in ('dir /s/b/ad Proxy') do rd "%%i")
) ELSE (
sleep 10 && goto Loop
)

I also tried this way here:

SET ProcessorUsage = wmic path Win32_PerfFormattedData_PerfProc_Process get Name,PercentProcessorTime | findstr /i /c:RenderQuery

:Loop
for %ProcessorUsage% LSS 2 do (
(for /f "delims=" %%X in ('dir /s/b/ad Proxy') do for /f "delims=" %%Y in ('dir /s/b/a-d "%%X"') do move "%%Y" ".\03. Proxy") && (for /f "delims=" %%i in ('dir /s/b/ad Proxy') do rd "%%i") || (sleep 10 && goto Loop)
)

With these scripts I tried to create the window that only blinks and closes right away...

What's the best way to do this?

EDIT

Explaining in more detail: I work with video production, so I constantly need to render Proxy files, which are video files with low quality to be used during my video editing and replaced at the end of editing, this makes the much smoother video editing.

Having said that, I have a folder model, inside this folder model there is a folder where I always download the video files from the camera and in that folder there is always a .bat file that opens all the video files in the software that generates proxy files of the camera's video files.

This .bat file has this exact code:

start "" "C:\Users\User\Downloads\FFmpeg_Batch_AV_Converter_Portable_2.8.4_x64\FFBatch.exe" -f "%~dp0\"

When this software opens, it automatically renders the proxy files and their output is always in a child folder of the original files folder, and the name of the folder is Proxy.

The issue is that I don't want them to be in several separate Proxy folders, so I created another .bat file that is in the parent folder of all video files, this script contains exactly these lines:

for /f "delims=" %%X in ('dir /s/b/ad Proxy') do for /f "delims=" %%Y in ('dir /s/b/a-d "%%X"') do move "%%Y" ".\03. Proxy"

for /f "delims=" %%i in ('dir /s/b/ad Proxy') do rd "%%i"

That is, it only searches recursively for files that are inside folders named Proxy, then it moves these files to the folder 03. Proxy that is inside the parent folder.

The second line looks for all proxy folders (which are now empty) and deletes them.

The point is: I currently run the second script manually, as soon as the render finishes, and I would like it to run automatically.

Given this, I thought of adding a line in the first script, which opens the video files in the rendering program, this line would call the second script in the background, and the second script would be analyzing the CPU usage of this application every 10 seconds, and when the usage is less than 2% (in theory there is nothing else rendering, since it has a low CPU usage) it executes the lines that move the files and remove the folders.

I think there's a good change for this to work, because this software renders 4 videos at a time, and this means that there is no time between stopping rendering a video and starting another... the CPU usage is always very high until all the videos are finished, so I think this would be the best signal to release the other commands.

CodePudding user response:

As far as the scripts causing the command window to blink and close instantly you can run the scripts from the command prompt and the output will stay on screen. This might be helpful for you to see what is going wrong with your current script.

From you question it looks like you are trying to do some kind of secondary operation when RenderQuery is finished processing those requests.

It look like they way you are doing this is by watching the execution of RenderQuery and waiting until it is sleeping and then doing some kind of file operation.

Be advised that threads can sleep for many reasons other than being finished with a operation. A thread could be sleeping because a higher priority thread is running or because it needs to access a memory page from disk. Because of this using the CPU usage of a process is not a reliable way to tell if it is done.

The best way to do this for a given process is dependent on that specific application. For this answer I am giving a generic solution.

The ideal way to trigger a secondary operation when a process finishes a request is by having the process itself signal that it is finished with a task or having it start running the secondary operation. If the process does not support this and can not be modified to support this then this is not a option.

A second safe way is to check for the existence of specific signs that the process is complete on the system. A good example of a possible sign like this is the presence of a file of a specific minimum size on the file system that only exists larger than that size when the initial task is completed. If the size of such a file when completed is unknown then another option is to check for the presence of specific signatures in the file (Like seeing if it is a valid PNG image). Once the signature is detected you can start the secondary operation.

CodePudding user response:

I did some more testing and created a Powershell script that does what I need.

In these tests that I did, I realized that the FFBatch process does not consume CPU, in fact it opens instances of ffmpeg.exe and those do consume CPU, but with that I could see something even more interesting, at the end of the process the instances of ffmpeg.exe are closed and this can be a signal to move on to the next code.

With that in mind, I set up a script in Powershell like this:

# This pause at the beginning is to wait until ffmpeg is open, otherwise the variable will be null
Start-Sleep 10
            
Do{
$ffmpeg = Get-Process ffmpeg -ErrorAction SilentlyContinue
Write-Host "test"
Start-Sleep 2
            
}until([bool] $ffmpeg -eq $false)
Write-Host "Works!" 

This works flawlessly, and I believe it's better than using CPU utilization, as pointed out several times here.

The question now is: is it possible to convert this to a .bat?

I really preferred using a .bat because all the other scripts are in CMD, besides, .bat files are a bit easier to run than Powershell scripts.

  • Related