Greetings,
I am attempting to create a script using WinWaitExist and SendKeysto and am having a problem. If I run the script on Windows XP/7, it works great but doesn't function on Windows 8.1. From what I can tell, the script can "see" the window it's supposed to send the keys to but nothing happens. I've tried using SendkeysTo, SendKeysCHild and even Sendkey with no success. Is there something additional I need to do in my script for this to work on Windows 8.1?
Quote from: bettman on November 11, 2013, 10:07:17 AM
Greetings,
I am attempting to create a script using WinWaitExist and SendKeysto and am having a problem. If I run the script on Windows XP/7, it works great but doesn't function on Windows 8.1. From what I can tell, the script can "see" the window it's supposed to send the keys to but nothing happens. I've tried using SendkeysTo, SendKeysCHild and even Sendkey with no success. Is there something additional I need to do in my script for this to work on Windows 8.1?
1) Is UAC enabled or disabled on Windows 7 and Windows 8.1, respectively?
2) If UAC is enabled, how were both the script process and the application process [that owns the target window] launched w/respect to elevation [e.g. "run as administrator]?
UAC is disabled on both machines
Disabling UAC on Windows 8 or Windows 8.1 doesn't really disable it. All it does is turn off the security elevation prompt. What that means is that if you are using an administrator group account, most applications are running with a restricted access token but WinBatch is executing with the full admin access token. To test if UAC is the cause of your problem, change your script's file extension from ".wbt" to ".wbt_af" and then see if the ".wbt_af" version has the same problem.
What does changing the file extension do? I am running compiled scripts (exe's) on the machines and not scripts from within Winbatch Studio.
Quote from: bettman on November 12, 2013, 08:39:32 AM
What does changing the file extension do? I am running compiled scripts (exe's) on the machines and not scripts from within Winbatch Studio.
The different script file extensions are associated with different builds of the WIL Interpreter that have different manifests for UAC. This allows you control the degree of elevation/escalation and UI protection that is required when executing your script directly through the interpreter. However, when you compile a script, you can specify the same types of manifest options to be placed into the EXE file that the WinBatch+Compiler produces as output.
The whole reason for asking about UAC has to do with the situation where your script is running as a normal user or as a restricted administrator, while the window being targeted by the SendKey*() functions is owned by a process that is running elevated. In such a situation, you will find that the UI protection of the elevated process prevents your script from sending simulated keystrokes to the specified window.
Could you please tell me how I would set the UAC settings in the script such that the Sendkeys function will work?
Quote from: ChuckC on November 12, 2013, 09:29:32 AM
The whole reason for asking about UAC has to do with the situation where your script is running as a normal user or as a restricted administrator, while the window being targeted by the SendKey*() functions is owned by a process that is running elevated. In such a situation, you will find that the UI protection of the elevated process prevents your script from sending simulated keystrokes to the specified window.
As of Windows 8 attempting UI access from an elevated process to a standard or restricted administrator process can run afoul of UAC restrictions as well.
Quote from: td on November 12, 2013, 10:24:36 AM
As of Windows 8 attempting UI access from an elevated process to a standard or restricted administrator process can run afoul of UAC restrictions as well.
That's an unpleasant complication of things.
Quote from: bettman on November 12, 2013, 09:40:16 AM
Could you please tell me how I would set the UAC settings in the script such that the Sendkeys function will work?
You can change the UAC settings for compiled scripts by launching the Configuration Settings dialog form the 'Settings..." button in the compiler. However, it is not possible to tell you exactly which of the UAC settings you should use because there are several different UAC related scenarios that could be causing the problem. If fact, it is not even certain that UAC is the cause of your problem. Using uncompiled scripts with several different extensions is a good way to quickly test the hypothesis. Of course that approach doesn't work as well if you don't have a machine with both the targeted application and WinBatch installed. In that case, you would need to compile with different UAC settings to see if UAC is the cause of the problem.
Here is tech. db article that explains the relationship between UAC settings and script file extensions.
http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/tsleft.web+WinBatch/Vista+Manifests~In~WinBatch~Explained.txt (http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/tsleft.web+WinBatch/Vista+Manifests~In~WinBatch~Explained.txt)
I tried something a little different by putting a Windows hotkey combination (Ctrl-Esc) into the script and it worked so it doesn't appear to be blocked. The dialog I'm attempting to send the keystrokes to appears to have the same title and process on Win7 and Win8. I've tried hardcoding the title of the dialog into a Sendkeysto statement and also using WinItemProdIC(ProdID, 0,1) to get the Title name with no success. Is there another way to send keystrokes to a process dialog?
At this point it might be helpful to see the failing code and the actual error. I recommend using DebugTrace. Simply add DebugTrace(@on,"trace.txt") to the beginning of the script and inside any UDF, run it until the error or completion, then inspect the resulting trace file for clues as to the problem
Feel free to post the trace file here ( removing any private info) if you need further assistance.
Here is the code in question:
list=tListProc()
Lookfor = ItemlocateWild('msra*',List,@tab,1)
ProcString=ItemExtract(Lookfor,List,@tab)
ProcStringLen = StrLen(ProcString)
ProcID=StrSub(ProcString,6,ProcStringLen)
Title = WinItemProcID(ProcID,0,1)
Winactivate(Title)
Timedelay(2)
SendKeysTo('%Title%~','{TAB 2}')
Timedelay(2)
SendKeysto('%Title%~','{Enter}')
TimeDelay(2)
Thank you for your help.
This is a dump of the debug trace file:
************************************************************
*** Debug Initialized ***
==============================
Wed 11/13/2013 12:01:11 PM
WinBatch 32 2013C
WIL DLL 6.13cmc
\\dtemgmt1p\upload\Scripts\RemoteAssistancePrompt.exe
Windows platform: NT, version: 6.2, build: 9200
ErrorMode: @OFF
Valid Code Signature: No
UAC Manifest Settings: level="asInvoker" uiAccess="false"
UAC Elevation Level: Admin Not Elevated
==============================
Platform="Unknown"
(16) VALUE STRING => "Unknown"
Timeout = 60
(16) VALUE INT => 60
If v=="2-5-1" ;"Windows XP"
(16) ELSE DO==>TRUE
AgentRunning = AppExist('msra.exe',1,120)
(688) VALUE INT => 1
If AgentRunning == @false
(688) ELSE DO==>TRUE
list=tListProc()
(750) VALUE STRING => "Idle|0 System|4 smss|316 csrss|404 csrss|464 wininit|472 winlogon|516 services|564 lsass|572 svchost|632 svchost|660 dwm|756 LogonUI|772 svchost|804 svchost|848 svchost|892 svchost|952 ClassicShellService|336 svchost|384 spoolsv|940 svchost|1040 ccSvcHst|1284 vmtoolsd|1388 TPAutoConnSvc|1760 svchost|1864 dllhost|1916 WmiPrvSE|1964 msdtc|2232 Smc|2600 unsecapp|2904 csrss|2148 winlogon|2864 dwm|3056 ClassicStartMenu|3192 TPAutoConnect|3224 conhost|3236 ccSvcHst|3276 rdpclip|3284 taskhostex|3296 explorer|3508 svchost|3780 SearchIndexer|3956 vmtoolsd|3212 svchost|3696 regedit|2652 cmd|1484 conhost|736 cmd|2108 conhost|1172 msra|1344 audiodg|3140 RemoteAssistancePrompt|3340"
Lookfor = ItemlocateWild('msra*',List,@tab,1)
(750) VALUE INT => 50
ProcString=ItemExtract(Lookfor,List,@tab)
(750) VALUE STRING => "msra|1344"
ProcStringLen = StrLen(ProcString)
(750) VALUE INT => 9
ProcID=StrSub(ProcString,6,ProcStringLen)
(750) VALUE STRING => "1344"
IntControl (35, 2000, 0, 0, 0)
(750) VALUE STRING => "25"
Title = WinItemProcID(ProcID,0,1)
(750) VALUE UNICODE => Windows Remote Assistance
SendKeysTo('Windows Remote Assistance~','{TAB 2}')
(2860) VALUE INT => 0
SendKeysto('Windows Remote Assistance~','{Enter}')
(4922) VALUE INT => 0
exit
(4922) VALUE INT => 0
--- Normal termination ---
;;;END OF JOB;;;
Ok. I see you are running a compiled script called RemoteAssistancePrompt.exe. The following DebugTrace header indicates:
ErrorMode: @OFF
Valid Code Signature: No
UAC Manifest Settings: level="asInvoker" uiAccess="false"
UAC Elevation Level: Admin Not Elevated
First ErrorMode should only be turned OFF for a single line of code. Please see: http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/tsleft.web+WinBatch+Two~Minute~Lecture~on~ErrorMode~No-Nos.txt. I recommend removing ErrorMode(@off) while debugging. Otherwise it can turn a five minute debugging session into a week long nightmare.
First try recompiling the script using the requireAdmin UAC manifest Setting. Test the newly compiled exe. Success?
If not successful...I see the code is not code signed and the UI access is set to false.
I wonder if the code needs the following settings, on a Windows System with UAC enabled :
- Manifest uiAccess set to TRUE
- EXE is 'Code Signed'
- EXE is installed in or under the "Program Files" folder or in the "Windows\System32" folder
You can test this theory by running a uncompiled script ( this assumes WinBatch is installed on this system) . All uncompiled scripts meet this criteria.
We have confirmed that SendKey/SendKeysTo will fail if a WinBatch script runs AsInvoker and your are attempting to send keys to an elevated process ( a process run with admin privileges). This is expected behavior. You will need to Run Your script at the same integrity level as the running application that you want to send keystrokes to.
I suspect your 'msra.exe' process is running elevated, therefor you will need to specify RequireAdministrator UAC manifest setting when compiling your script. You can change the UAC settings for compiled scripts by launching the Configuration Settings dialog from the 'Settings..." button in the compiler. Set the "requested execution level" to RequireAdministrator and "UI Access" to FALSE.
This sounds like a nice info tidbit to add to the standing "about UAC" articles in the database.
Quote from: kdmoyers on November 15, 2013, 05:23:29 AM
This sounds like a nice info tidbit to add to the standing "about UAC" articles in the database.
I agree. I created the following tech article that hopefully explains the situation. http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/tsleft.web+WinBatch/UAC+SendKey~and~UAC.txt
The tech article isn't quit actuate for Windows 8.whatever because on Windows 8.whatever almost all processes run with medium integrity level even for administrator accounts with UAC prompting turned off.
This is unlike Windows 7 where almost all processes run with high integrity level for administrators with UAC prompting turned off.
Quote from: td on November 15, 2013, 09:06:10 AM
The tech article isn't quit actuate for Windows 8.whatever because on Windows 8.whatever almost all processes run with medium integrity level even for administrator accounts with UAC prompting turned off.
This is unlike Windows 7 where almost all processes run with high integrity level for administrators with UAC prompting turned off.
Tony,
I get the same results from my test code on Window 8.1, logged in admin, with either
Default UAC setting or UAC set to
Never Notify.
;WORKS: Logged in as Admin, Script with default .WBT extention (HighestAvilable)
;WORKS: Logged in as Admin, Script with .WBT_AF extention (RequireAdministrator)
;EXPECTED FAIL: Logged in as Admin, Script with .WBT_IF extention (AsInvoker)
uaclevel = "Error or unsupported platform.;Process is default (UAC is disabled or standard user).;Process is running elevated.;Process is not running elevated (user is in Administrators group)."
Pause('UacElevationLevel of Script',ItemExtract(UacElevationLevel()+1,uaclevel,";"))
;Launch an Elevated Process
ShellExecute("cmd.exe", "", "", @NORMAL, "RunAs")
parentwindowname = "Admin"
ret = WinWaitExist( parentwindowname, 5 )
if ret == 0
Pause("Notice","Unable to access specified window")
Exit
endif
;Attempt to sendkeys
SendKeysTo( parentwindowname, "Hello World." )
That's my point.
To clarify, it is the 'With User Account Control (UAC) fully enabled' clause that is not correct or at least misleading with regard to Windows 8. On Windows 8 UAC does not need to be fully enabled.