Page 1 of 2
CPU History on title
Posted: 30 Nov 2013 17:17
by einstein1969
Hi,
I have made this code for display the CPU usage on title bar.
This show a history like a graphics on the title bar
I have two problem:
- There are output of set /a that i don't want visible.
- There are strange error on initial startup.
I have investigated but without being able to find why
Experts Needed!
EDIT: thanks to penpen i have resolved. this is worked version on seven 32bit
An more readable and reliability (work better) version by penpen is
hereCode: Select all
@echo off & setlocal EnableDelayedExpansion & if not "%1"=="" goto %1
chcp 850
rem sample of 5 seconds
start "" /B %0 title_cpu 5
pause
goto :eof
:title_cpu %1=sample_interval_sec
shift
set "counter=\Processore(_Total)\%% Tempo Processore" & rem italian version
rem set "counter=\processor(_total)\%%%% processor time" & rem english version
typeperf "!counter!" -si %1 | cmd /v:on /c"set S=_,..~-=ùùïî&set Bcpu= &for /L %%n in () do @(set v=&set /p v=&if defined v (set cpu=^!v:*,=^!&set cpu= ^!cpu:~1,-6^!&set /a i=^!cpu:~0^,-2^!*10/100>nul 2>nul&if defined i for %%b in (^!i^!^) do @(set Bcpu=^!Bcpu^!^!S:~%%b,1^!^)&set Bcpu=^!Bcpu:~-50^!&title CPU:^!cpu:~-5^!%% ^!Bcpu^!^)^) "
goto :eof
Einstein1969
Re: CPU History on title
Posted: 30 Nov 2013 19:44
by penpen
I'm currently using WinXP home, that has no typeperf.exe, so i only can try to solve this:
einstein1969 wrote:- There are output of set /a that i not want visible.
As you are using set /A wthin the cmd shell (and not a bat/cmd script),
you may want to redirect the unwanted output to nul (>nul), or
you may want to execute the part after the '|' from a bat/cmd script where this output isn't produced.
May i use this to simulate a valid output of typeref (format guessed),
or is the format wrong, or are there missing info/empty lines
(maybe such lines are causing the problem, if yes just filter using findstr/find)?
Code: Select all
setlocal enableDelayedExpansion
(
for /L %%a in (11,1,30) do for /L %%b in (0,1,9) do echo "!date!!time!","%%a.%%b01234"
)>"typeref.txt"
endlocal
Tomorrow i'll have a closer look at your script (too late now, sry).
penpen
Edit: Changed the typeref simulated output.
Re: CPU History on title
Posted: 01 Dec 2013 11:48
by einstein1969
Hi penpen,
thanks for replay.
I have added the >nul and 2>nul for the problem and now working.
The output of typeperf is this:
Code: Select all
"(PDH-CSV 4.0)","\\ACER-ASP-5100\Processore(_Total)\% Tempo Processore"
"12/01/2013 18:44:54.935","3.125000"
"12/01/2013 18:44:55.935","1.562500"
"12/01/2013 18:44:56.935","3.125000"
the first line may create problem but i don't wanted add other process. This use very low cpu for display this info. <0,3%
thanks again penpen!
einstein1969
Re: CPU History on title
Posted: 01 Dec 2013 11:56
by penpen
I think, i have found a possible problem:
You are using "for /L" and "set /P" to read the piped data.
There is no guarantee that the line is fully written to the pipe, before "set/p" has read the data fully.
Additionally there is no guarentee, that the typeperf output waits, until "set/p" has read the line, before additional data is written to the pipe.
As a result the lines could be messed up, especially, when loading first.
So you have to parse the data to lines, or better let another program (for example findstr) let do this.
So with the "set/A" redirected to nul this may help you (only the piped line):
Code: Select all
type typeperf.txt | cmd /V:ON /C "@echo off&set S=_,.-ùïî&set Bcpu=K&for /F %%a in ('findstr ","') do (set v=%%a&if defined v (set cpu=!v:*,=!&set cpu= !cpu:~1,-6!&(set /a i=!cpu:~0,-2!*6/100)>nul&for %%b in (!i!) do @(set Bcpu=!Bcpu!!S:~%%b,1!)&set Bcpu=!Bcpu:~-30!&title CPU:!cpu:~-5!%% !Bcpu!))"
penpen
Edit: You may avoid using cmd /V:ON ... by using "typeperf ...|" within the for loop prior to findstr.
Re: CPU History on title
Posted: 01 Dec 2013 15:54
by einstein1969
penpen wrote:I think, i have found a possible problem:
You are using "for /L" and "set /P" to read the piped data.
There is no guarantee that the line is fully written to the pipe, before "set/p" has read the data fully.
Additionally there is no guarentee, that the typeperf output waits, until "set/p" has read the line, before additional data is written to the pipe.
As a result the lines could be messed up, especially, when loading first.
So you have to parse the data to lines, or better let another program (for example findstr) let do this.
So with the "set/A" redirected to nul this may help you (only the piped line):
Code: Select all
type typeperf.txt | cmd /V:ON /C "@echo off&set S=_,.-ùïî&set Bcpu=K&for /F %%a in ('findstr ","') do (set v=%%a&if defined v (set cpu=!v:*,=!&set cpu= !cpu:~1,-6!&(set /a i=!cpu:~0,-2!*6/100)>nul&for %%b in (!i!) do @(set Bcpu=!Bcpu!!S:~%%b,1!)&set Bcpu=!Bcpu:~-30!&title CPU:!cpu:~-5!%% !Bcpu!))"
penpen
Edit: You may avoid using cmd /V:ON ... by using "typeperf ...|" within the for loop prior to findstr.
first i have tried
Code: Select all
@echo off & setlocal EnableDelayedExpansion & if not "%1"=="" goto %1
chcp 850
rem goto :test
rem goto :scopre
start "" /B %0 title_cpu 5
pause
goto :eof
:title_cpu %1=sample_interval_sec
shift
set "counter=\Processore(_Total)\%% Tempo Processore" & rem italian version
rem set "counter=\processor(_total)\%%%% processor time" & rem english version
typeperf "!counter!" -si %1 | cmd /V:ON /C "@echo off&set S=_,.-ùïî&set Bcpu=K&for /F %%a in ('findstr ","') do (set v=%%a&if defined v (set cpu=!v:*,=!&set cpu= !cpu:~1,-6!&(set /a i=!cpu:~0,-2!*6/100)>nul&for %%b in (!i!) do @(set Bcpu=!Bcpu!!S:~%%b,1!)&set Bcpu=!Bcpu:~-30!&title CPU:!cpu:~-5!%% !Bcpu!))"
goto :eof
but is blocked , nothing appear
but this work : typeperf "!counter!" -si %1 | findstr ","
what do you mean with "parse the data to lines" . I have undestand the problem with set /p .
But I don't know what do findstr in this case.
Einstein1969
Re: CPU History on title
Posted: 01 Dec 2013 17:46
by penpen
einstein1969 wrote:...
but is blocked , nothing appear
Curious thing, that the above does not work as i expect... with "type typeperf.txt | ..." it works without problems on my WinXP home... .
I fear, that i have to test it on a system with typeperf (may take a while).
einstein1969 wrote:what do you mean with "parse the data to lines" . I have undestand the problem with set /p .
But I don't know what do findstr in this case.
With "parse the data to lines" i wanted to say you have to reconstruct the text lines on the receiver side of the pipe (sender | receiver).
The program findstr searches for pattern of texts linewise, so it reconstructs the lines, and if using within a "for/F" loop the reconstructed lines are assigned to the loop variable(s) if specified.
penpen
Re: CPU History on title
Posted: 01 Dec 2013 17:56
by penpen
Right now, i see an error in my above post... "tokens=* delims=" is missing in the for loop i have posted..., sry for that (and the type command is wrong, too).
With some good luck this may be the reason for the lock.
So this should be the corrected line:
Code: Select all
typeperf "!counter!" -si %1 | cmd /V:ON /C "@echo off&set S=_,.-ùïî&set Bcpu=K&for /F "tokens=* delims=" %%a in ('findstr ","') do (set v=%%a&if defined v (set cpu=!v:*,=!&set cpu= !cpu:~1,-6!&(set /a i=!cpu:~0,-2!*6/100)>nul&for %%b in (!i!) do @(set Bcpu=!Bcpu!!S:~%%b,1!)&set Bcpu=!Bcpu:~-30!&title CPU:!cpu:~-5!%% !Bcpu!))"
penpen
Re: CPU History on title
Posted: 01 Dec 2013 18:56
by einstein1969
penpen wrote:Right now, i see an error in my above post... "tokens=* delims=" is missing in the for loop i have posted..., sry for that (and the type command is wrong, too).
With some good luck this may be the reason for the lock.
So this should be the corrected line:
Code: Select all
typeperf "!counter!" -si %1 | cmd /V:ON /C "@echo off&set S=_,.-ùïî&set Bcpu=K&for /F "tokens=* delims=" %%a in ('findstr ","') do (set v=%%a&if defined v (set cpu=!v:*,=!&set cpu= !cpu:~1,-6!&(set /a i=!cpu:~0,-2!*6/100)>nul&for %%b in (!i!) do @(set Bcpu=!Bcpu!!S:~%%b,1!)&set Bcpu=!Bcpu:~-30!&title CPU:!cpu:~-5!%% !Bcpu!))"
penpen
I don't try this because is late. I will tomorrow. But the question is:
findstr wait that the stream in input ending before processing?
The initial script launch typeperf in an endless mode.
I'm looking a long time for a method that processing the input while the output is generated. But seem the alternative is using only set /p
I search this method for interprocess communication for parallel processing sync too.
Einstein1969
Re: CPU History on title
Posted: 02 Dec 2013 06:35
by penpen
einstein1969 wrote:...
But the question is:
findstr wait that the stream in input ending before processing?
The initial script launch typeperf in an endless mode.
I'm looking a long time for a method that processing the input while the output is generated. But seem the alternative is using only set /p
I search this method for interprocess communication for parallel processing sync too.
Yes, findstr is buffering data before it displays it.
Normally this may be fixed using find, but the "for /F" loop seems to buffer, too.
Code: Select all
Z:\>(echo 1,&echo 2,& echo 3,&echo pause,&((ping 192.168.0.10 -n 1 -w 5000)>nul
2>nul)&echo 4,&echo 5,& echo 6,) | (@echo off&find /N ",")
versus
Z:\>(echo 1,&echo 2,& echo 3,&echo pause,&((ping 192.168.0.10 -n 1 -w 5000)>nul
2>nul)&echo 4,&echo 5,& echo 6,) | (@echo off&for /F %a in ('find /N ","') do ec
ho %a)
You may be forced to use a batch at the receiver side of the pipe with a goto loop and "set/P", if "for /L" is buffering, too.
AND it looks like there is a problem using "for /L"/"set/P"
:
Code: Select all
Z:\>(echo 1,&echo 2,& echo 3,&echo pause,&((ping 192.168.0.10 -n 1 -w 5000)>nul
2>nul)&echo 4,&echo 5,& echo 6,) | cmd /V:ON /C "(@echo off&for /L %a in (1,1,20
) do (set v=&set /P v=&echo [%a]!v!))"
[1]1,
[2]4,
[3]5,
[4]!v!
[5]!v!
[6]!v!
[7]!v!
[8]!v!
[9]!v!
[10]!v!
[11]!v!
[12]!v!
[13]!v!
[14]!v!
[15]!v!
[16]!v!
[17]!v!
[18]!v!
[19]!v!
[20]!v!
penpen
Edited: Corrected the "for /L"/"set/P" problem.
Re: CPU History on title
Posted: 02 Dec 2013 07:51
by penpen
Additionally: Sad to say that set /P seems to have problems with pipes, when any line ending character is involved, so you have to reformat the data (replace the newlines, carriage returns) before sending it to the pipe.
If you would replace the line end chars by a '#' and avoid '=' chars, then this is a simple piping and line reconstructing example:
Code: Select all
::source.bat
@echo off
setlocal
for %%a in (a b c d e # f g h i j # k l m n o p #) do <nul set /p "=%%a"
for %%a in (a b c d e f g #) do <nul set /p "=%%a"
for %%a in (h i j k l m n o p #) do <nul set /p "=%%a"
<nul set /p "=q"
endlocal
Code: Select all
::pipeOut.bat
@echo off
cls
setlocal enableDelayedExpansion
echo:%0: started
set "buffer="
set "line="
set "endOfStream=q"
:readkey
set "input="
set /p "input="
if DEFINED input goto :inputAvailable
goto :readkey
:inputAvailable
set "buffer=%buffer%%input%"
echo:%0: input="%input%", buffer="%buffer%"
:detectLine
if not defined buffer goto :noBuffer
set "line=%buffer:*#=%"
if defined line (
set "line=!buffer:%line%=!"
) else (
set "line=%buffer%"
)
if defined line (
set "buffer=%buffer:*#=%"
echo line found: "%line:~0,-1%", buffer="!buffer!"
goto :detectLine
)
:noBuffer
set "isEndOfStream=!input:%endOfStream%=%endOfStream%_!"
if %input% == %isEndOfStream% goto :readkey
echo:%0: leaving
endlocal
penpen
Re: CPU History on title
Posted: 02 Dec 2013 08:56
by einstein1969
penpen wrote:einstein1969 wrote:...
But the question is:
findstr wait that the stream in input ending before processing?
The initial script launch typeperf in an endless mode.
I'm looking a long time for a method that processing the input while the output is generated. But seem the alternative is using only set /p
I search this method for interprocess communication for parallel processing sync too.
Yes, findstr is buffering data before it displays it.
Normally this may be fixed using find, but the "for /F" loop seems to buffer, too.
Code: Select all
Z:\>(echo 1,&echo 2,& echo 3,&echo pause,&((ping 192.168.0.10 -n 1 -w 5000)>nul
2>nul)&echo 4,&echo 5,& echo 6,) | (@echo off&find /N ",")
versus
Z:\>(echo 1,&echo 2,& echo 3,&echo pause,&((ping 192.168.0.10 -n 1 -w 5000)>nul
2>nul)&echo 4,&echo 5,& echo 6,) | (@echo off&for /F %a in ('find /N ","') do ec
ho %a)
You may be forced to use a batch at the receiver side of the pipe with a goto loop and "set/P", if "for /L" is buffering, too.
AND it looks like there is a problem using "for /L"/"set/P"
:
Code: Select all
Z:\>(echo 1,&echo 2,& echo 3,&echo pause,&((ping 192.168.0.10 -n 1 -w 5000)>nul
2>nul)&echo 4,&echo 5,& echo 6,) | cmd /V:ON /C "(@echo off&for /L %a in (1,1,20
) do (set v=&set /P v=&echo [%a]!v!))"
[1]1,
[2]4,
[3]5,
[4]!v!
[5]!v!
[6]!v!
[7]!v!
[8]!v!
[9]!v!
[10]!v!
[11]!v!
[12]!v!
[13]!v!
[14]!v!
[15]!v!
[16]!v!
[17]!v!
[18]!v!
[19]!v!
[20]!v!
penpen
Edited: Corrected the "for /L"/"set/P" problem.
the problem seem not the FOR /L
Code: Select all
(echo 1,&echo 2,& echo 3,&echo pause,&((ping 192.168.0.10 -n 1 -w 5000)>nul2>nul)&echo 4,&echo 5,& echo 6,) | cmd /V:ON /C "(@echo off&set v=&set /P v=&echo [1]!v!&set v=&set /P v=&echo [2]!v!&set v=&set /P v=&echo [3]!v!&set v=&set /P v=&echo [4]!v!&set v=&set /P v=&echo [5]!v!&set v=&set /P v=&echo [6]!v!&set v=&set /P v=&echo [7]!v!&set v=&set /P v=&echo [8]!v!)"
[1]1,
[2]4,
[3]5,
[4]6,
[5]!v!
[6]!v!
[7]!v!
[8]!v!
Einstein1969
Re: CPU History on title
Posted: 02 Dec 2013 10:13
by einstein1969
penpen wrote:Additionally: Sad to say that set /P seems to have problems with pipes, when any line ending character is involved, so you have to reformat the data (replace the newlines, carriage returns) before sending it to the pipe.
If you would replace the line end chars by a '#' and avoid '=' chars, then this is a simple piping and line reconstructing example:
Code: Select all
::source.bat
@echo off
setlocal
for %%a in (a b c d e # f g h i j # k l m n o p #) do <nul set /p "=%%a"
for %%a in (a b c d e f g #) do <nul set /p "=%%a"
for %%a in (h i j k l m n o p #) do <nul set /p "=%%a"
<nul set /p "=q"
endlocal
Code: Select all
::pipeOut.bat
@echo off
cls
setlocal enableDelayedExpansion
echo:%0: started
set "buffer="
set "line="
set "endOfStream=q"
:readkey
set "input="
set /p "input="
if DEFINED input goto :inputAvailable
goto :readkey
:inputAvailable
set "buffer=%buffer%%input%"
echo:%0: input="%input%", buffer="%buffer%"
:detectLine
if not defined buffer goto :noBuffer
set "line=%buffer:*#=%"
if defined line (
set "line=!buffer:%line%=!"
) else (
set "line=%buffer%"
)
if defined line (
set "buffer=%buffer:*#=%"
echo line found: "%line:~0,-1%", buffer="!buffer!"
goto :detectLine
)
:noBuffer
set "isEndOfStream=!input:%endOfStream%=%endOfStream%_!"
if %input% == %isEndOfStream% goto :readkey
echo:%0: leaving
endlocal
penpen
umh, this is work for only one line?
I need that work for a variable number of lines.
Other question on this type of working is :
How to detect CR or LF or the pair in any order and trasform it?
In the mini-monitor i have found a solution that use two trick : 1) use of start, 2 use of more
Seem that cmd versus start is the difference for working set /p a little better
The other
important question is :
why this is more stable?
Code: Select all
>start "" /B cmd /c "echo 1,&echo 2,&echo 3,&echo pause,&((ping 192.168.0.10 -n 1 -w 5000)>nul2>nul)&echo 4,&echo 5,& echo 6," | cmd /V:ON /c "@echo off&for /L %a in (1,1,2000) do (set v=&set /P v=&if defined v echo [%a]!v!)"
[1]1,
[2]2,
[3]3,
[4]pause,
[5]4,
[6]5,
[7]6,
EDIT: This work with /WAIT also
Einstein1969
Re: CPU History on title
Posted: 02 Dec 2013 10:40
by penpen
einstein1969 wrote:umh, this is work for only one line?
I need that work for a variable number of lines.
It is for a variable number of line, but it is transmitted as one line:
source text file wrote:line 1
line 2
...
line n
coded source text file to send it through the pipe wrote:line1#line2#...#linen#q
You may transmit any number of lines you want, you just have to avoid using '#', 'q', '=', NL, CR, and some problematic control characters, i assume. (should all not be in the typeperf output, if i see it right).
einstein1969 wrote:The other important question is :
why this is more stable?
Code: Select all
>start "" /B cmd /c "echo 1,&echo 2,&echo 3,&echo pause,&((ping 192.168.0.10 -n 1 -w 5000)>nul2>nul)&echo 4,&echo 5,& echo 6," | cmd /V:ON /c "@echo off&for /L %a in (1,1,2000) do (set v=&set /P v=&if defined v echo [%a]!v!)"
[1]1,
[2]2,
[3]3,
[4]pause,
[5]4,
[6]5,
[7]6,
EDIT: This work with /WAIT also
Although this indeed seems to be more stable on my WinXP home, this sometimes return wrong results, too:
Code: Select all
Z:\>start "" /B cmd /c "echo 1,&echo 2,&echo 3,&echo pause,&((ping 192.168.0.10
-n 1 -w 5000)>nul2>nul)&echo 4,&echo 5,& echo 6," | cmd /V:ON /c "@echo off&for
/L %a in (1,1,2000) do (set v=&set /P v=&if defined v echo [%a]!v!)"
[1]1,
[2]2,
[3]4,
[4]5,
penpen
Edit: Added 'q' to the forbidden characters.
Re: CPU History on title
Posted: 02 Dec 2013 11:02
by penpen
I've just got a flash of inspiration, but it will only work, if you are able to make typeperf to output only one measured value:
Code: Select all
:: reserved file name, is not allowed to contain any space: "abort.txt"
set abort=abort.txt
if exist %abort% echo Unexpected critical error: Reserved file "%abort%" is in use.&goto :eof
copy nul %abort% /Y
:loop
if not exist %abort% goto :eof
@echo off
set S=_,.-ùïî
set Bcpu=K
for /F "tokens=* delims=" %%a in ('type typeperfOne.txt ^| findstr ","') do (
set v=%%a
if defined v (
set cpu=!v:*,=!
set cpu= !cpu:~1,-6!
(set /a i=!cpu:~0,-2!*6/100)>nul
for %%b in (!i!) do @(set Bcpu=!Bcpu!!S:~%%b,1!)
set Bcpu=!Bcpu:~-30!&title CPU:!cpu:~-5!%% !Bcpu!
)
)
goto :loop
You only have to replace "type typeperfOne.txt" with the typeperf command that only forces one measure value.
This way it costs some more performance, but it should work.
The endless loop is breaked, if you delete the file specified by the variable abort.
The main advantage: Much more readable
.
penpen
Re: CPU History on title
Posted: 03 Dec 2013 05:04
by einstein1969
penpen wrote:I've just got a flash of inspiration, but it will only work, if you are able to make typeperf to output only one measured value:
Code: Select all
:: reserved file name, is not allowed to contain any space: "abort.txt"
set abort=abort.txt
if exist %abort% echo Unexpected critical error: Reserved file "%abort%" is in use.&goto :eof
copy nul %abort% /Y
:loop
if not exist %abort% goto :eof
@echo off
set S=_,.-ùïî
set Bcpu=K
for /F "tokens=* delims=" %%a in ('type typeperfOne.txt ^| findstr ","') do (
set v=%%a
if defined v (
set cpu=!v:*,=!
set cpu= !cpu:~1,-6!
(set /a i=!cpu:~0,-2!*6/100)>nul
for %%b in (!i!) do @(set Bcpu=!Bcpu!!S:~%%b,1!)
set Bcpu=!Bcpu:~-30!&title CPU:!cpu:~-5!%% !Bcpu!
)
)
goto :loop
You only have to replace "type typeperfOne.txt" with the typeperf command that only forces one measure value.
This way it costs some more performance, but it should work.
The endless loop is breaked, if you delete the file specified by the variable abort.
The main advantage: Much more readable
.
penpen
For me, unfortunately, one of the requirements for an application that monitors the cpu usage is to use little CPU and few processes. Anyway, thank you for giving a more readable form. The insert in the first post stands out as before.
Einstein1969