Some questions about the new version of WB (Specifically about IgnoreInput())

Started by snowsnowsnow, October 29, 2020, 05:36:39 PM

Previous topic - Next topic

snowsnowsnow

First of all, you all should congratulate me - I am now a paid up owner of the latest version of
WinBatch.  Hooray for me!  I needed to go this route specifically to get a version of IgnoreInput() that
works in Windows 10.  I am working on cat-proofing a laptop.

N.B. (!!!) I know what I'm talking about - I do not want "lock screen" in the usual sense - even though I
refer to it as such in the text belo.  I want what IgnoreInput() does.

However, I have a few questions about this new version:

1) How to make UAC nonsense go away (every time I run a script)?

Every time I run a .WBT file (from the Command Prompt), it comes up with a UAC prompt.
How to make this go away?

(The option on the screen seems to imply that it would be possible to turn all UAC prompting off, which,
really when you get right down to it, would actually be a good thing, but it seems extreme.  Is there
some way to turn it off only for WinBatch (but not for everything else) ?

2) How to do IgnoreInput() thing right?  Any way to do it permanently (does it really break when you do a
Pause()?)

I've noticed that if I do IgnoreInput(1), it stops working (i.e., the computer becomes responsive again),
if either of the following happens:
    a) The script exits  (I'd actually like it to stay on after script exit!)
    b) The script does something like Pause()

AFAICT, the only way to keep the IgnoreInput() in effect is to do a long (i.e., infinite) TimeDelay().
I want it to stay locked until the user hits Ctrl/Alt/Del.  But what I really want, of course, is for the
script to pause until the user hits C/A/D, then wake up and prompt again for "Should I re-lock?".  The
problem is that this simple script doesn't work:

WHILE 1
    Pause("Should I lock it?","Hit escape to exit now")
    IgnoreInput(1)
ENDWHILE

And, as an aside, is IgnoreInput() guaranteed to be proof against anything other than C/A/D ?
In my testing, it seems to be, but I would like the official word.

3) What is max value for TimeDelay() ?

Just out of curiosity, is that any maximum value for TimeDelay()?

Alternatively, is there any other function to just cause the script to suspend indefinitely?

td

Quote from: snowsnowsnow on October 29, 2020, 05:36:39 PM
First of all, you all should congratulate me - I am now a paid up owner of the latest version of
WinBatch.  Hooray for me!  I needed to go this route specifically to get a version of IgnoreInput() that
works in Windows 10.  I am working on cat-proofing a laptop.

I have first-hand experience with our family cat sending email messages and thank you again for your support.

Quote
1) How to make UAC nonsense go away (every time I run a script)?

Every time I run a .WBT file (from the Command Prompt), it comes up with a UAC prompt.
How to make this go away?

You can make it go away in several ways. As you mention you can turn UAC prompting off.  If you are using Windows 10 this is not as onerous as it sounds because UAC is still hard at work.  On Windows 7 it does turn off UAC.

Another alternative is to us the version of the WinBatch executable manifested with "asInvoker" and "false" which can be done by changing your script's file name extension to ".wbt_af.  Your is a Tech Database artical that covers the different WinBath executables and script file extensions:

https://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/nftechsupt.web+WinBatch/Vista+Manifests~In~WinBatch~Explained.txt

Quote

2) How to do IgnoreInput() thing right?  Any way to do it permanently (does it really break when you do a
Pause()?)


It doesn't really "break" IgnoreInput.  When you call the "Pause" function along with several other UI related functions, input is temporarily enabled but it is restored to the previous state before the function returns.  You could try calling the Win32 function "BlockInput" using a DllCall. I am not sure if this will get you closer to what you are attempting to do but it might be worth the attempt.  Poking around in the Tech Database might also prove useful.


https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-blockinput


Quote
I've noticed that if I do IgnoreInput(1), it stops working (i.e., the computer becomes responsive again),
if either of the following happens:
    a) The script exits  (I'd actually like it to stay on after script exit!)
    b) The script does something like Pause()

AFAICT, the only way to keep the IgnoreInput() in effect is to do a long (i.e., infinite) TimeDelay().
I want it to stay locked until the user hits Ctrl/Alt/Del.  But what I really want, of course, is for the
script to pause until the user hits C/A/D, then wake up and prompt again for "Should I re-lock?".  The
problem is that this simple script doesn't work:

WHILE 1
    Pause("Should I lock it?","Hit escape to exit now")
    IgnoreInput(1)
ENDWHILE

And, as an aside, is IgnoreInput() guaranteed to be proof against anything other than C/A/D ?
In my testing, it seems to be, but I would like the official word.


No, it is not guaranteed. When the process that is blocking input terminates or there is a some kind of kernel exception the OS automagically unblocks input.  The reason for this is self-evident.  And if I recall correctly, when a script is running as a standard user newer versions of Windows ignore IgnoreInput. Now for additional weasel words; there are other events that can enable input but these events are not well documented by MSFT and very from version to version of Windows.

Quote
3) What is max value for TimeDelay() ?

Just out of curiosity, is that any maximum value for TimeDelay()?

It is about 2,147,483,647 seconds.

Quote
Alternatively, is there any other function to just cause the script to suspend indefinitely?

There is the TimeWait function which causes a script to pause until a specific date/time.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

snowsnowsnow

The saga continues - or, two things that don't work:

1) I renamed it to ignore.wbt_af, but I still get a UAC prompt when I run it.

2) The script (ignore.wbt_af) doesn't work as expected:

Code (winbatch) Select

WHILE 1
    Pause("Press OK to lock machine...","")
    IgnoreInput(1)
    WHILE IgnoreInput(-1)
TimeDelay(10)
    ENDWHILE
ENDWHILE


What I'm looking for, of course, is a way for the WB script to detect that the user has re-enabled input.  Why doesn't checking IgnoreInput(-1) periodically work?

Would it be better to use BlockInput() directly (via DllCall) ?

ChuckC

Quote from: snowsnowsnow on October 29, 2020, 05:36:39 PM
I am working on cat-proofing a laptop.

Nothing is ever cat-proof.  At best, it can be said to be cat-resistant for a non-infinite period of time.


td

Quote from: snowsnowsnow on October 30, 2020, 10:33:49 AM
The saga continues - or, two things that don't work:

1) I renamed it to ignore.wbt_af, but I still get a UAC prompt when I run it.

Sorry about that.  Your result is do to me committing a typo again.   The extension should be ".wbt_if".  However, see below.

Quote
2) The script (ignore.wbt_af) doesn't work as expected:

Code (winbatch) Select

WHILE 1
    Pause("Press OK to lock machine...","")
    IgnoreInput(1)
    WHILE IgnoreInput(-1)
TimeDelay(10)
    ENDWHILE
ENDWHILE


What I'm looking for, of course, is a way for the WB script to detect that the user has re-enabled input.  Why doesn't checking IgnoreInput(-1) periodically work?

The function will only report the status of the last call to the function or the default WinBatch setting if the function has not bee previously called.  It cannot detect if some external event or process reenabled input.

Quote
Would it be better to use BlockInput() directly (via DllCall) ?

It would work better in the sense that you might* be able to detect system input status when events other than those generated by WinBatch cause that status to change.

Also, to quote from the WIL function's topic, " Only processes with full administrator or system privileges can block user input.  The Windows operation system effectively ignores this function when it is called from a process with standard user or restricted administrator account privileges."  This is also true of the Win32 function.

* Untested hypothesis.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

snowsnowsnow

I think I've got it working.  First of all, I think the right "extension" is "IT" (just remember it).  I read the tech db article; it seems without the T, you don't have access to the UI.  Which means that IgnoreInput() or anything else in USER32.DLL won't work.  But with "IT", it works (and doesn't UAC prompt).

The following program (ignore.wbt_it) works (as proof of concept):

Code (winbatch) Select
u32 = DllLoad("user32")
WHILE 1
    Pause("Press OK to lock machine...","")
    IgnoreInput(1)
    WHILE !DllCall(u32,long:"BlockInput",long:1)
        TimeDelay(10)
    ENDWHILE
ENDWHILE


If you call BlockInput() directly, it will return 0 (indicating an error) if you try to block input when it is already blocked.  Why can't the WB IgnoreInput() function provide the same functionality?

(I know the answer is: Because it was decided not to, but I question the wisdom of that decision...)

td

Whether the choice is "it" or "if" depends on how the UAC group policy is set and the version of Windows you are using.  Generally, on Windows 10 setting uiaccess to "TRUE" the 't' will get you in more trouble than on Windows 7.  Windows 10 can require prompting when an application is set to 't' even if being executed by a standard user with execution level set to as invoke.  Which functions do or do not require 't' can vary depending on the versions of Windows.  This includes quite a bit of variation between Windows 10 feature updates.  Also remember that many systems are configured to require that the executable manifested to uiAccess = TRUE be launched from a "secure" folder.  That fact that IngoreInput even works without full administrative access is an undocumented change to Windows made at some point by MSFT.

Anyway, it is much appreciated that you figured it out for yourself.     

IgnoreInput works the way it does for a good reason.   It is not just an arbitrary decision.             
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

snowsnowsnow

QuoteIgnoreInput works the way it does for a good reason.   It is not just an arbitrary decision.             

Hmmm.  I'd like to know what that good reason is/was.  Care to share?

Anyway, I've discovered another anomaly/problem with it.  Consider:

Code (winbatch) Select
WinShow("")
Pause("Get","ready...")
IgnoreInput(1)
TimeDelay(10)
; Point A
Pause("Now","Check to see if input is blocked...")
; Point B
TimeDelay(10)
Pause("And now","We are done")


Run this, After hitting OK to the first Pause(), do C/A/D during the first TimeDelay() to unblock input.  Wait for the next Pause().  Hit OK.  Now check to see if input is blocked.  You will find that it is blocked - even though it wasn't blocked before the Pause().

The point is that at Point A, input is unblocked, but after the Pause() (at Point B), it is blocked.  This is because WB "thinks" it was still blocked before the Pause(), so after the Pause() (at Point B), it re-blocks.  This is just plain wrong...

td

And thank you for pointing out the way IngnoreInput works with the "uiAccess=TRUE" manifest setting.  We will change the function's documentation to reflect that.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

Should have added that we always appreciate user taking the time to provide suggestions and feedback.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

A note on using IgnoreInput on Windows 10.  At least in our testing, IgnoreInput does nothing when executed from a script with the extension ".wbt_it" with UAC settings a more or less defaults and the account executing the script is a Standard user instead of a reduced privilege Administrator account.  So to use ".wbt_it" with ignore input you need an administrator account.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

snowsnowsnow

Interesting.  I guess all I can say is "Works for me".

I'm guessing this means that the user account I am using is an administrator account.

BTW, the laptop is a "Walmart special" - configured whatever dorky way the people who set up these things would set it up.  We've done nothing to config the UAC settings or Group Policy or anything like that (or anything like that).  I think the initial config (first boot after getting it home) asked for a user id and we put in somebody's initials...

Edit to add: How can the situation be this chaotic??  It seems like it is just freakin' random!!  How can anyone develop software in this environment, when it seems like you never know what is going to happen on any particular machine at any particular time?  It seems to depend on the phase of the moon...

ChuckC

The Win32 API is peppered with functions that have had varying levels of usefulness over time, with some of them becoming far less useful as security-related changes have been implemented in newer versions of Windows.  It is likely that the functionality related to ignoring input is one of those kludges that hasn't stood up well as the operating system has aged.

Rather than burning endless hours trying to coerce a quirky feature into working reliably, you might do better to fall back on a hardware solution like the following:

https://www.invisiblefence.com/solutions/indoor

With the ability to set a 3' radius for a protected area, the "Micro Shields" would be suitable for placing near the laptop and warding off unwanted feline keyboard & touch screen activity.

I use one to keep a stubborn beagle from entering a particular room and visiting a corner that she finds irresistible when it comes to leaving a wet spot on the carpet.