I have a powershell script:

$i = 0 $delay = 1000 while($i -eq 0) { $myshell = New-Object -com "Wscript.Shell" $myshell.sendkeys("q") Start-Sleep -m $delay } 

It works but instead of sending a key only for a moment, I want to simulate pressing a key for a while, e.g. 1 second.

3

1 Answer

To send multiple keystrokes to whatever with sendkeys, you can just do this ( no real need for the WScript stuff):

Add-Type -AssemblyName System.Windows.Forms [System.Windows.Forms.SendKeys]::SendWait('q'*3) # Results <# qqq #> 

If you are trying to do this against a time state, then you need to provide that. So, that means setting up a stopwatch.

An example of a timer with a form:

Add-Type -AssemblyName Microsoft.VisualBasic, PresentationCore, PresentationFramework, System.Drawing, System.Windows.Forms, WindowsBase, WindowsFormsIntegration $delay = 10 $Counter_Form = New-Object System.Windows.Forms.Form $Counter_Form.Text = "Countdown Timer!" $Counter_Form.Width = 450 $Counter_Form.Height = 200 $Counter_Label = New-Object System.Windows.Forms.Label $Counter_Label.AutoSize = $true $Counter_Form.Controls.Add($Counter_Label) while ($delay -ge 0) { $Counter_Form.Show() $Counter_Label.Text = "Seconds Remaining: $($delay)" start-sleep 1 $delay -= 1 } $Counter_Form.Close() 

Using a timer object, a short example:

$Timer = New-Object system.diagnostics.stopwatch $Timer.Start() Start-Sleep -Milliseconds 1001 $Timer.Stop() $timer # Results <# IsRunning Elapsed ElapsedMilliseconds ElapsedTicks --------- ------- ------------------- ------------ False 00:00:01.0055471 1005 10055471 #> 

So, you end up going down the above, with your code.

Add-Type -AssemblyName System.Windows.Forms $Timer = New-Object system.diagnostics.stopwatch $Timer.Start() while ($Timer.ElapsedMilliseconds -le 1000) {[System.Windows.Forms.SendKeys]::SendWait('q')} # Results <# qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq #> 

Using a delay/sleep

Add-Type -AssemblyName System.Windows.Forms $Timer = New-Object system.diagnostics.stopwatch $Timer.Start() while ($Timer.ElapsedMilliseconds -le 1000) { Start-Sleep -Milliseconds 100 [System.Windows.Forms.SendKeys]::SendWait('q') } # Results <# qqqqqqq #> 

Update based on SilBee's comment:

Taking action on any keypress.

Add-Type -AssemblyName System.Windows.Forms $Timer = New-Object system.diagnostics.stopwatch $Timer.Start() while ($Timer.ElapsedMilliseconds -le 1000) { $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | OUT-NULL [System.Windows.Forms.SendKeys]::SendWait('q') Start-Sleep -Milliseconds 100 } 'Done' $Timer # Results <# Done IsRunning Elapsed ElapsedMilliseconds ElapsedTicks --------- ------- ------------------- ------------ True 00:00:02.0041171 2004 20041490 q #> 

If you are only after a specific key, then the $Host object still provides that.

$Host.UI.RawUI.ReadKey() # Results <# q VirtualKeyCode Character ControlKeyState KeyDown -------------- --------- --------------- ------- 81 q NumLockOn True #> 

Thus you can code for a specific letter, then branch to whatever other code you choose.

A rough example, could be something like this:

Add-Type -AssemblyName System.Windows.Forms $Timer = New-Object system.diagnostics.stopwatch $Timer.Start() while (($Host.UI.RawUI.ReadKey()).Character -eq 'q') { [System.Windows.Forms.SendKeys]::SendWait('q') Start-Sleep -Milliseconds 100 If ($Timer.ElapsedMilliseconds -ge 5000) {Break} } 'Done' $Timer # Results <# qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqDone IsRunning Elapsed ElapsedMilliseconds ElapsedTicks --------- ------- ------------------- ------------ True 00:00:05.0420154 5042 50420519 #> 

Again, the above is a user touching the keyboard, not a simulated event.

Trying to simulate that can/will lead to odd results/behavior with SendKeys, without a lot of fine-tuning and involving potentially calls to user32.dll.

It must be remembered, that press and hold is a mechanical action of the keyboard device (signal to the OS via the keyboard driver). There is no such thing in memory, which is where all code is fired.

4

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy