我有一个 powershell 脚本:
$i = 0
$delay = 1000
while($i -eq 0)
{
$myshell = New-Object -com "Wscript.Shell"
$myshell.sendkeys("q")
Start-Sleep -m $delay
}
Run Code Online (Sandbox Code Playgroud)
它可以工作,但我不想只发送一会儿按键,而是想模拟按下一个按键一段时间,例如 1 秒。
要使用 sendkeys 将多个击键发送到任何内容,您可以这样做(实际上不需要 WScript 的东西):
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.SendKeys]::SendWait('q'*3)
# Results
<#
qqq
#>
Run Code Online (Sandbox Code Playgroud)
如果您尝试针对时间状态执行此操作,那么您需要提供该时间状态。所以,这意味着设置一个秒表。
https://duckduckgo.com/?q=%27powershell+using+a+timer%27&t=h_&ia=web
带有表单的计时器示例:
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()
Run Code Online (Sandbox Code Playgroud)
使用计时器对象,一个简短的例子:
$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
#>
Run Code Online (Sandbox Code Playgroud)
所以,你最终会使用你的代码来完成上面的操作。
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
#>
Run Code Online (Sandbox Code Playgroud)
使用延迟/睡眠
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
#>
Run Code Online (Sandbox Code Playgroud)
根据SilBee's评论更新:
对任何按键执行操作。
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
#>
Run Code Online (Sandbox Code Playgroud)
如果您仅在特定键之后,那么 $Host 对象仍然提供该键。
$Host.UI.RawUI.ReadKey()
# Results
<#
q
VirtualKeyCode Character ControlKeyState KeyDown
-------------- --------- --------------- -------
81 q NumLockOn True
#>
Run Code Online (Sandbox Code Playgroud)
因此,您可以为特定字母进行编码,然后分支到您选择的任何其他代码。
一个粗略的例子可能是这样的:
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
#>
Run Code Online (Sandbox Code Playgroud)
再次强调,上面是用户触摸键盘,而不是模拟事件。
尝试模拟这种情况可能会导致 SendKeys 出现奇怪的结果/行为,而无需进行大量微调并涉及对 user32.dll 的潜在调用。
必须记住,按住是键盘设备的机械动作(通过键盘驱动程序向操作系统发出信号)。内存中没有这样的东西,所有代码都是在内存中触发的。
| 归档时间: |
|
| 查看次数: |
15114 次 |
| 最近记录: |