Check batch (.bat) for whole numbers?

Ma
6

I started writing batch files. As the first "big" project I had to write a file where you enter a number and there should be a countdown that changes every minute (Example: Input: 1 [for one hour], Countdown: 60 after one) Minute: 59, etc.). The aim of the file is that the PC or laptop after the entered time in the energy saving mode is set. Does jmd have an idea for the countdown that changes every minute? If jmd still finds errors or improvements that can write to me also like.

(see code, line: 11/12)

echo countdown:
@echo off
title timer
echo Insert time (in hours):
set / P time = Time:
set standardtime =% time% * 60 * 60
set mtime =% time% * 60 * 60
: loop
set / a mtime =% mtime% -1
if% mtime% == 0 goto timeisup
if% standardtime% / 60-% mtime% / 60 ==? Echo% time% - (% standardtime% / 60-% mtime% / 60)
ping localhost -n 2> nul
goto loop
: timeisup
echo time is up!
% windir% \ system32 \ rundll32.exe PowrProf.dll, SetSuspendState 0,1,0
break> nul
exit

re

If only integers are calculated, then N mod 60 = 0 if and only if N - M * 60 = 0, where M = N / 60

ma

First, the reference to a serious mistake!

% time% is a system variable. This can be overwritten with you, but then you can't access the current prehistory in the batch. Although this is irrelevant in the present case, but bad habits can be quite unlearn again…

demo:

echo% time%
set time = 20
echo% time%
pause

now to your batch:

everything necessary is commented in the batch:

@echo off
title timer
echo Insert time (in hours):
set / P "_hours = hours:"
set "toMinutes =% _ hours% * 60

: loop
if% toMinutes% equ 0 goto timeisup
calculate remaining hours and minutes for display.
rem batch always calculates with integers without decimal places.
rem ergo we divide the minute countdown for the hours by 60 and with a modulo we get the minute percentage
set / a "viewHours =% toMinutes% / 60, viewMinutes =% toMinutes% %% 60"
format the display of the minutes in two places
Remumber the number plump to a 0
set "viewMinutes = 0% viewMinutes%"
rem handed over only the last two digits
set "viewMinutes =% viewMinutes: ~ -2%"

echo time to standby:% viewHours%:% viewMinutes%
rem since you update the countdown every single minute anyway we let ping wait 60 seconds
rem this is more accurate than having the batch loop make any elaborate checks every second that apply to 1/60 only
rem to test kanst You instead of 61 and 1 or 2 register, then you do not have to wait hours…
ping localhost -n 61> nul
rem the counter may be counted down after the waiting time otherwise he comes a minute early…
set / a "toMinutes =% toMinutes% -1
goto loop

: timeisup
echo time is up!
rem standby for test purposes switched off first…
::% windir% \ system32 \ rundll32.exe PowrProf.dll, SetSuspendState 0,1,0
break> nul

Ma

Thank you very much.

@PerfectMuffin

If only integers are calculated, then N mod 60 = 0 if and only if N - M * 60 = 0, where M = N / 60

I did not understand that xD That was too high for me ^^

@Erzesel

now to your batch:

everything necessary is commented in the batch

Ma

I have another question about the power save mode command.

The standby is more like the PC would shut down…

How is it possible that this is as if I click on "Energy saving mode" in the Windows Start menu?

ma

The thing with the Standby or belongs to the delicate things.

If hibernation is allowed for the system then…

rundll32.exe PowrProf.dll, SetSuspendState

… Do not go into standby mode, but go to hibernation. The parameters 0,1,0 are irrelevant, because SetSuspendState expects three booleans as parameters and not three strings or numbers! For rundll32 is just too stumpsinnig. And so the parameters are ignored and the saved standard is used.

In principle, it could be very simple:

switch off the rest condition
powercfg / hibernate off
rundll32.exe powrprof.dll, SetSuspendState
rem after waking up, turn on the power again
powercfg / hibernate on
pause

Unfortunately, the switching of the idle state variable by powercfg only works with admin rights. Which means that this batch must be run as admin to work as desired!

There's also a solution for almost every problem.

So the C # code looks for the standby:

PCsleep.cs

using System.Runtime.InteropServices;
namespace PCsleep
{
class program
{
// function definition
[DllImport ("Powrprof.dll", SetLastError = true)]
static external uint SetSuspendState (bool hibernate, bool forceCritical, bool disableWakeEvent);
static void Main ()
{
// let the machine fall asleep
SetSuspendState (false, false, false);
}
}
}

… However, this can't be done directly in the batch.

But Batch can start a Powerschell one-liners… (the i is like a shot through the knee in the eye)

This works without admin rights.

sleep.cmd

powershell.exe -C "$ m = '[DllImport (\" Powrprof.dll \ ", SetLastError = true)] static external bool SetSuspendState (bool hibernate, bool forceCritical, bool disableWakeEvent); public static void PowerSleep () {SetSuspendState ( false, false, false);} '; add-type -name import -member $ m -namespace dll; [dll.import] :: powerSleep (); "

This is a pretty long command line and does the same thing as the C # code, just directly from a batch.

You can use this line directly in your batch instead of rundll32.exe PowrProf.dll, SetSuspendState.

If you prefer to compile the above c # program into an, exe, or the batch to compile C # code.

compile C # .cmd:

@echo off
for / f "tokens = * delims =" %% v in ('dir / b / s / a: -d / o: -n "% SystemRoot% \ Microsoft.NET \ Framework \ * csc.exe"') do (
set "csc = %% v"
)
if "% csc%" == "" (
echo no C # compiler found
echo please install a Microsoft-dotNet Framework
pause
exit / b
)
echo "% csc%" found
"% csc%" / nologo /out:"%~dpn1.exe ""% ~ 1 "> compile.log && (
echo success…
echo…% ~ dpn1.exe…

) || (
echo compilererror…
echo:
type compile.log
)

Ma

Many thanks.