Windows 10 Enterprise
Version 20H2
I am writing a VBScript that handles a print to PDF dialogue window.
The goal:
Detect that the printer dialogue window is open (using a loop that continuously checks)
If/when detected, handle the dialogue (send the filename, send the file path, click "print" to finish)
The problem: for some reason, the sub endlessly loops through an If statement. I don't understand why the code is looping through a section containing no loop code.
The code basically sends the same keys in a loop over and over again within the dialogue window, never completing the If statement.
As a small aside, I think the sendKeys command I use to close the dialogue is incorrect, but that should not cause an IF statement to loop.
Code (go to the section indicated by "#"'s to see where I am having issues):
Sub handlePrintDial()
iSeconds = 20
'================================================================================
' Set time variables
'================================================================================
tNow = now()
tFuture = DateAdd("s",iSeconds,tNow)
'================================================================================
' Set other objects
'================================================================================
Set WshShell = CreateObject("WScript.Shell")
sApp = "Save Print Output As"
sFileName = "This is a test-" & Year(now()) & Month(now()) & Day(now()) & Hour(now()) & Minute(now()) & Second(now())
'================================================================================
' Loop until window opens or time elapses
'================================================================================
Do Until Now() > tFuture
ret = WshShell.AppActivate(sApp)
If ret = True Then
Exit Do
End If
Loop
If ret <> True Then
MsgBox "Printer window not found. Please try again."
Exit Sub
End If
'================================================================================
' If printer window detected, handle window
'================================================================================
WScript.Sleep 500
ret = WshShell.AppActivate(sApp)
'########This is the top of the endless loop####################
If ret = True Then
ret = wshShell.AppActivate(sApp)
' Send filename
WScript.Sleep 2000
wshShell.sendKeys sFileName
WScript.Sleep 2000
' Send file path to save to
wshShell.sendKeys "{F4}"
WScript.Sleep 2000
wshShell.sendKeys "{BS}"
WScript.Sleep 2000
wshShell.sendKeys "^A"
WScript.Sleep 2000
wshShell.sendKeys "{del}"
WScript.Sleep 2000
wshShell.sendKeys "C:\Users\Username\Desktop\closeDialogue.vbs"
WScript.Sleep 2000
' "Click" print to complete the dialogue window
wshShell.sendKeys "{enter}"
WScript.Sleep 2000
wshShell.sendKeys "{enter}"
WScript.Sleep 2000
End If
WScript.Sleep 500
'########This is the bottom of the endless loop####################
WScript.Quit
End Sub
Call handlePrintDial()
Here is the window I am trying to handle:
After some experimentation, I discovered that the sendKeys "{enter}" commands were mysteriously causing the script to execute again (two simultaneous instances of the code running at once, per command line). When I removed Enter keys, the code ran normally without kicking off new instances of the script.
Summary: use sendKeys at your own peril. Specifically, it appears {enter} can cause the code to have unusual problems.
Related
I'm new so please forgive me if I'm wrong. I'm using this code here where I am getting a
Expected Statement - Line 3 Char 1
Code:
Set wshShell =wscript.CreateObject("WScript.Shell")
dowscript.sleep100wshShell.sendkeys
"{CAPSLOCK}"wshshell.sendkeys
"{NUMLOCK}"wshshell.sendkeys "{SCROLLLOCK}"
loop
Any ideas?
EDIT: When trying to put that code within an existing loop like below I get invalid charecter line 1 char 1
Set oWMP = CreateObject("WMPlayer.OCX.7" )
Set colCDROMs = oWMP.cdromCollection
if colCDROMs.Count >= 1 then
do
For i = 0 to colCDROMs.Count - 1
colCDROMs.Item(i).Eject
Next ' cdrom
For i = 0 to colCDROMs.Count - 1
colCDROMs.Item(i).Eject
Next ' cdrom
loop
End If
Set wshShell = WScript.CreateObject("WScript.Shell")
Do
WScript.Sleep 100
wshShell.Sendkeys "{CAPSLOCK}"
wshshell.Sendkeys "{NUMLOCK}"
wshshell.Sendkeys "{SCROLLLOCK}"
Not sure where you copied this from, but it's lost spaces and line breaks, which is why you get the error
Expected Statement - Line 3 Char 1
when executing it. The code should read;
Set wshShell = WScript.CreateObject("WScript.Shell")
Do
WScript.Sleep 100
wshShell.Sendkeys "{CAPSLOCK}"
wshshell.Sendkeys "{NUMLOCK}"
wshshell.Sendkeys "{SCROLLLOCK}"
Loop
It's a fairly basic script that loops forever with a 100 millisecond wait (to stop the machine from completely freezing as the OS battles with the script) and sends the key sequence CAPSLOCK, NUMLOCK and SCROLLLOCK. To me, it just looks like a prank script designed to flash the LED key indicators on most standard QWERTY keyboards in sequence, over and over.
It's worth noting VBScripts in general are not designed to run forever and writing infinite loops like this one can have varying results.
I'm running a VBScript that communicates to an exe file in Windows 7.
The VBScript works great!
The issues I have, is that once the PC has been in locked, goes to sleep or hiberation the VBScript doesn't communicate with the exe application.
The VBScript is running (I have a log that tells me every time a loop is complete, but its not communicating to the exe.
Below is code that is not working when the PC is locked.
Set WSHShell = WScript.CreateObject("WScript.Shell")
' info for exporting data
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0
Dim fso, MyFile, FileName, TextLine, cycles
Dim I
I = 0
Dim n
n = .1 'how often the program saves the data (in minutes)
cycles = 2 'how many times it will save
FileName = "C:\Users\Desktop\new.txt" 'location where the log file will save
Dim sl
sl = n * 60000 'change from seconds to ms for the sleep function
Set fso = CreateObject("Scripting.FileSystemObject")
' Open the file for output
Set MyFile = fso.OpenTextFile(FileName, ForAppending, True, TristateTrue)
' Write to the file.
MyFile.WriteLine "Log file for recording data from Yokogawa MX100 (" & cycles
& " cycles)"
WSHShell.Run "MXStandardE.exe"
WScript.Sleep 1000
WSHShell.AppActivate "MXStandardE.exe"
WScript.Sleep 1000
Do while I < cycles
a = Now()
WScript.Sleep 1000
WSHShell.Run "MXStandardE.exe"
WScript.Sleep 1000
WSHShell.AppActivate "MXStandardE.exe"
WScript.Sleep 1000
WSHShell.SendKeys "%A"
WScript.Sleep 1000
WSHShell.SendKeys "{DOWN}"
WScript.Sleep 1000
WSHShell.SendKeys "{ENTER}"
I = I + 1
MyFile.Writeline I & " of " & cycles & " at " & a & " --time of each cycle is
" & n & " minutes"
WScript.Sleep sl 'when sl is used loop time is in minutes
Loop
MyFile.Close
MsgBox ("Script has completed")
As Ansgar already said, it's pretty obvious that nothing will work while the PC sleeps or hibernates. In the case where the PC is locked, techniques that rely on window management or direct input such as SendKeys won't work as expected, because the user's session, along with user-level applications, is essentially shelved to make way for the login screen or another user.
You might want to do some research into the SendMessage/PostMessage API, or you can stop using VBScript and replace it with a Scheduled Task or system service that runs using a local service account, assuming you just want to execute an exe without any UI interaction.
The question is: do you need to go under hibernation or pc suspension? If not, you should simply configure or turn off those settings. By only locking the session, the vbscript should be run and generate an outpout without any trouble. By checking and configuring advanced windows energy settings it might help you solving this.
Any kind of user input will do. Here's the code I have so far.
Set WshShell = WScript.CreateObject("WScript.Shell")
Dim Account
Account = 111111
WScript.Sleep 5000
Do
WScript.Sleep 400
WshShell.SendKeys "drill "
WshShell.SendKeys Account
WshShell.SendKeys "{ENTER}"
Account = Account + 1
Loop
Basically it's a code guesser (for a game) and I want to be able to interrupt it with any kind of user input.
I don't think we have any direct solution. Below code seeks for user interaction after 50 iterations. If yes, control exits from do loop. You can play around with other ways to interrupt the loop and of course you can change the counter as per your need.
Set WshShell = WScript.CreateObject("WScript.Shell")
Dim counter
Dim Account
Dim msgResult
counter = 0
Account = 111111
WScript.Sleep 5000
Do
WScript.Sleep 400
WshShell.SendKeys "drill "
WshShell.SendKeys "drill "
WshShell.SendKeys Account
WshShell.SendKeys "{ENTER}"
Account = Account + 1
If counter = 50 Then 'get user input after 50 iterations
msgResult = MsgBox("Do you want to exit?", vbYesNo)
If msgResult = vbYes Then 'if yes
Exit Do
End If
End If
counter = counter + 1
If counter > 101 then
counter =0
End If
Loop
I have written a simple script to press ok on message box but its not working. Please help me how to do this
here is the sample code
set oWShell = createobject("WScript.Shell")
MsgBox "Hello"
WScript.Sleep 2000
oWShell.Sendkeys "{enter}"
MsgBox waits for the click. If you don't click yourself, it gets never to "Sleep" or "SendKeys".
I assume you are just trying to learn, because this code makes no sense. If you want to press a button on another programs window, this could work. But in its own process this doesn't work.
If you really want to click your own MsgBox, you have to do it with a separate script. One creates the MsgBox and another clicks the button.
If you just want to close a message box after a certain period of time, check out the Popup() method of the WshShell class. Its second parameter specifies the number of seconds to display the message box for before closing it.
With CreateObject("WScript.Shell")
' Display a message box that disappears after two seconds...
.Popup "Hello", 2
End With
chek this site
you need this:
Set objArgs = WScript.Arguments
messageText = objArgs(0)
MsgBox messageText, 51, "Warning......!"
how to click on button in message box and control of display time here the script can do that .
just copy this lines of code and paste in text file then save it as "ControlMsgBox.vbs".
''' IN THE NAME OF ALLAH
' THIS SCRIPT CONTROL OF MSGBOX DISPLAY TIME
' LET SENKEYS DEAL WITH THE MSGBOX
' SOLVE THE PROBLEM OF APPACTIVATE NOT WORKING EFFECTIVE
On Error Resume Next
Dim Sh : Set Sh=CreateObject("wscript.shell") ' declare and create the wshshell
Dim path : path =Replace(WScript.ScriptFullName,WScript.ScriptName,"") 'declare the variable of the current script path
Dim myMessage : myMessage="This is my message ." 'declare variable of the of the display text of msgbox
Sh.run "cmd.exe /c cd """&path&""" && echo msgbox """&myMessage&""",,""hello"" > mymsgbox.vbs",0,false 'create masgbox script in the same path
WScript.Sleep 1000 'wait 1 sec to let process of create msgbox script execute
Sh.run "mymsgbox.vbs" 'run the created msgbox script
WScript.Sleep 3000 ' let the msgbox display for 3 sec before we sendkeys to close
For i=0 To 600 ' loop to retry select correct msgbox window about 1 min
ret = Sh.AppActivate("In_The_Name_Of_Allah") 'select the activate msgbox window (if this loop 300 this mean loop will continue 30 sec if 600 (1 min)
If ret = True Then ' check if the msgbox windows select or not
Sh.SendKeys "%N" 'send key of Alt+N to select first button in msgbox (ok)
End If
ret = Sh.AppActivate("In_The_Name_Of_Allah") 'recheck again to be sure that we will not send key out of target windows (msgbox window)
If ret = True Then
Sh.SendKeys "{enter}" ' send key to click enter
wscript.sleep 500
ret=Sh.AppActivate("In_The_Name_Of_Allah")
If ret=False Then ' using nested IF to sure of selected windows is false because its close
Exit For ' exit for loop directly and execute what after for next
End If
End If
WScript.Sleep 100
Next
With CreateObject("Scripting.FileSystemObject")
If .FileExists(path&"mymsgbox.vbs") Then 'check if the msgbox script we create form this script exist or not
.DeleteFile(path&"mymsgbox.vbs") 'delete the msgbox script we create after message window closed
End If
End With
Set Sh=Nothing 'remove the sh object create
WScript.Quit ' terminate wscript.exe instance who run this script
I am new to use VB script. I am using the below code to connect my VPN. But the problem is that after entering "select" button in VPN client, the second page display is depending on Network Speed. Sometimes it is loaded within 4 sec, sometimes after 10 sec. Is there any code where i can get the VPN is fully loaded or not (like BUSY command for IE).
set WshShell=Wscript.CreateObject("Wscript.Shell")
WshShell.Run("""C:\\Program Files\Cisco\Anyconnect\vpnui.exe""")
WScript.Sleep 500
WshShell.SendKeys "{ENTER}"
WScript.Sleep 500
WshShell.SendKeys "username"
WshShell.SendKeys "rsa_no"
WshShell.SendKeys "password"
WScript.Sleep 500
WshShell.SendKeys "{ENTER}"
Whilst not vb script, I think this approach should still work.
I have the vpncli directory in my %path%
I have a batch file:
vpncli.exe connect xyz.123.com -s < d:\vpncreds.txt
with the credentials in a separate file (d:\vpncreds.txt):
username
password
y
Note: you need an empty line at the end.
This works fine here, and wonder if you take the credentials out of your VB script and put them in a separate file, it might achieve what you need to.
Also, if your credentials change, you only need to change the one file, and not the potential handful of script files if you access the vpn in multiple scripts.
Try my code below. Note that you may have to adjust sleep times (in milliseconds). To see what's happening in the command prompt, change the 2 in the 9th line to a 1.
Dim host, username, password, pathToClient
host = "yourHostURL"
username = "yourUsername"
password = "yourPassword"
pathToClient = "C:\Program Files {(}x86{)}\Cisco\Cisco AnyConnect Secure Mobility Client\vpncli.exe"
Set ws = WScript.CreateObject("WScript.Shell")
ws.run("TASKKILL.exe /F /IM vpnui.exe"), 0, false
ws.run("cmd.exe"), 2, false
ws.AppActivate("Command Prompt")
WScript.Sleep 300
ws.SendKeys """" & pathToClient & """ connect " & host & "~"
WScript.Sleep 1000
ws.SendKeys(username & "~")
WScript.Sleep 50
ws.SendKeys(password & "~")
ws.run("TASKKILL.exe /F /IM cmd.exe"), 0, false
Here is an improved version that doesn't wait for sleep timeouts, i.e. connects as soon as the window becomes visible. This works with the latest version of AnyConnect (4.10 as of writing).
' Script to automatically connect to Cisco AnyConnect.
' This script assumes that you have already set up your connection.
Const Password = "[YOUR PASSWORD]" ' Enter your password here
Const ConnectionUrl = "[YOUR CONNECTION URL]" ' Enter the URL of your endpoint (without HTTP prefix)
' Copy password to clipboard in case something goes wrong (to connect manually)
CopyToClipboard(Password)
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run """%PROGRAMFILES(x86)%\Cisco\Cisco AnyConnect Secure Mobility Client\vpnui.exe"""
ActivateWindow("Cisco AnyConnect Secure Mobility Client")
WshShell.SendKeys "{ENTER}"
ActivateWindow("Cisco AnyConnect | " + ConnectionUrl)
WshShell.SendKeys "{TAB}"
WshShell.SendKeys Password
WshShell.SendKeys "{ENTER}"
Function ActivateWindow(title)
Const Step = 100
Const Timeout = 10000
Dim Result
Dim Counter
For Counter = 0 To Timeout Step Step
Result = WshShell.AppActivate(title)
If Result Then Exit For
WScript.Sleep Step
Next
If Result = False Then
MsgBox("Window '" + title + "' not found.")
WScript.Quit
End If
End Function
Function CopyToClipboard(Input)
If IsNull(Input) Then
Set Clipboard = CreateObject("HTMLFile").parentWindow.clipboardData.getData("Text")
If IsNull(Clipboard) Then Clipboard = ""
Else
CreateObject("WScript.Shell").Run _
"mshta.exe javascript:eval(""document.parentWindow.clipboardData.setData('text','" _
& Replace(Replace(Replace(Input, "'", "\\u0027"), """","\\u0022"),Chr(13),"\\r\\n") & "');window.close()"")", _
0,True
End If
End Function