- HOME >
- Windows >
Windows
投稿日:
- Share
- Google+
- B!Hatena
- LINE
PowerShell script can simulate keyboard stroke.
This behavior can automate applications which do not support command line.
At this time, I made a script which run Notepad, input text and save it as a file.
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#Press Windows key [System.Windows.Forms.SendKeys]::SendWait(«^{ESC}») #Input «run» [System.Windows.Forms.SendKeys]::SendWait(«run») Start-Sleep -s 1 #Press Enter key [System.Windows.Forms.SendKeys]::SendWait(«{ENTER}») Start-Sleep -s 1 #Input «notepad» [System.Windows.Forms.SendKeys]::SendWait(«notepad») [System.Windows.Forms.SendKeys]::SendWait(«{ENTER}») Start-Sleep -s 1 #Input «This is a test script» [System.Windows.Forms.SendKeys]::SendWait(«This is a test script.») #Press Control+S key [System.Windows.Forms.SendKeys]::SendWait(«^s») Start-Sleep -s 1 [System.Windows.Forms.SendKeys]::SendWait(«newtext.txt») [System.Windows.Forms.SendKeys]::SendWait(«{ENTER}») Start-Sleep -s 1 #Press Alt+F4 key [System.Windows.Forms.SendKeys]::SendWait(«%{F4}») |
Explanation
This script just press keys by SendKeys.
The following page is the detail about keys.
VBScript — SendKeys Method — TechNet Articles — United States (English) — TechNet Wiki
Pressing Windows key cannot be simulated with another key. The script press Control+ESC, then input «run» and press enter.
In addition, there is a delay between pressing a key and showing dialog. A wait (1 second) may be needed to input a string.
Movie
The script is executed fast.
Basically, writing text and save it is done by a script (Not necessary to control GUI). However I made a script as an experiment.
powershell_keystroke
- Share
- Google+
- B!Hatena
- LINE
-Windows
-GUI, PowerShell
OK turns out what you really want is this: http://inputsimulator.codeplex.com/
Which has done all the hard work of exposing the Win32 SendInput
methods to C#. This allows you to directly send the windows key. This is tested and works:
InputSimulator.SimulateModifiedKeyStroke(VirtualKeyCode.LWIN, VirtualKeyCode.VK_E);
Note however that in some cases you want to specifically send the key to the application (such as ALT+F4
), in which case use the Form
library method. In others, you want to send it to the OS in general, use the above.
Old
Keeping this here for reference, it will not work in all operating systems, and will not always behave how you want. Note that you’re trying to send these key strokes to the app, and the OS usually intercepts them early. In the case of Windows 7 and Vista, too early (before the E
is sent).
SendWait("^({ESC}E)")
or Send("^({ESC}E)")
Note from here: http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx
To specify that any combination of SHIFT, CTRL, and ALT should be held
down while several other keys are pressed, enclose the code for those
keys in parentheses. For example, to specify to hold down SHIFT while
E and C are pressed, use «+(EC)». To specify to hold down SHIFT while
E is pressed, followed by C without SHIFT, use «+EC».
Note that since you want ESC
and (say) E
pressed at the same time, you need to enclose them in brackets.
Using while
Loop with SendKeys()
Method
Use the while
loop to invoke the SendKeys()
method for an unlimited time to keep the PC/Laptop screen active using PowerShell.
$wScriptShellObj = New—Object —Com «Wscript.Shell» while (1) { $wScriptShellObj.SendKeys(«.») Sleep 2 } |
Here, we used the New-Object
cmdlet to create an instance of the WSH (Windows Script Host) Shell object using COM (Component Object Model) technology and stored it in $wScriptShellObj
. This object lets the script interact with the Windows shell and run different shell commands.
Then, we entered an infinite loop using while(1)
that would keep it running until the script was terminated using Ctrl+C. Inside the loop, we used the SendKeys()
method of the $wScriptShellObj
object, which sent the .
to an active application once every 2
seconds. If we opened NotePad
, the script entered dots there, and if we opened NotePad++
, it printed dots there.
The SendKeys()
method simulated the keystroke as if it was typed/entered by the user. After each keystroke, the script paused for 2
seconds using the Sleep
command and then continued with the next iteration of the while
loop. This way, we can keep our PC screen active.
Using while
Loop with SendWait()
Method
Use the while
loop to call the SendWait()
method for an unlimited time to keep the PC/Laptop screen active using PowerShell. Press Ctrl+C to terminate the script.
while ($true) { [void][System.Reflection.Assembly]::LoadWithPartialName(‘System.Windows.Forms’) [System.Windows.Forms.SendKeys]::SendWait(«{NUMLOCK}») Start—Sleep —Seconds 2 } |
Again, we used a while
loop that would run unlimitedly because the condition $true
would always be True. Inside the while
loop, we used the LoadWithPartialName()
method of the System.Reflection.Assembly
class. Remember that the [System.Reflection.Assembly]
referred to the System.Reflection.Assembly
class in .NET, which provided properties and methods to work with assemblies.
We used the LoadWithPartialName()
method by specifying the 'System.Windows.Forms'
as an argument to load the System.Windows.Forms
assembly into the current PowerShell session. The [void]
cast was used to discard any value or output of the LoadWithPartialName()
method call. In addition, it was used to suppress any value produced while loading the assembly.
Why did we load the System.Windows.Forms
assembly? Loading was mandatory to ensure that the System.Windows.Forms.SendKeys
class would be available for use and provide methods to simulate the keystrokes.
Now, we used the SendWait() method of System.Windows.Forms.SendKeys
class to simulate hitting the NumLock key. Here, the "{NUMLOCK}"
string was passed as an argument to the SendWait()
method; this string argument specified the keystroke sequence to be sent.
After that, we used the Start-Sleep
cmdlet to sleep for two seconds. This cmdlet ensured that the statements within the loop would be executed every two seconds. This way, we can prevent our PC/Laptop from entering sleep mode or screen lock via simulating keystrokes and sending them to an active window or application.
Using keybd_event()
Method
Use the keybd_event()
method to keep the PC/Laptop screen active unlimitedly using PowerShell. Press Ctrl+C to stop this script.
$pInvokeSignature = @‘ [DllImport(«user32.dll»)] public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo); ‘@ Add—Type —MemberDefinition $pInvokeSignature —Namespace Win32Functions —Name KeyboardFunctions while ($true) { [Win32Functions.KeyboardFunctions]::keybd_event(0x90, 0, 0, 0) [Win32Functions.KeyboardFunctions]::keybd_event(0x90, 0, 2, 0) Start—Sleep —Seconds 2 } |
First, we defined a PInvoke signature for keybd_event()
from the user32.dll
in C#. This signature was stored in the $pInvokeSignature
variable, which allowed invoking the keybd_event()
function from the PowerShell using the Add-Type
cmdlet. Let’s break down the signature to understand it before diving into the Add-Type
and onwards.
To define a signature, We used the @''@
construct, known as verbatim string literal, to define a multiline string without interpreting escape sequences or escaping special characters. The @'
and '@
was used to start and end the verbatim string in PowerShell. Everything between them was taken as a literal string, including the special characters and line breaks.
Next, the [DllImport("user32.dll")]
specified that the keybd_event()
method would be imported from the user32.dll
library. After that, we declared the keybd_event() method with its signature. Following is a brief explanation of the different components of the keybd_event()
function declaration:
public
specified that function can be accessed outside the class.static
indicates that the function is astatic
method of the class, accessible without instantiating the class.extern
denoted that the function was implemented externally; in the above example, it was implemented in theuser32.dll
library.void
was the return type of the function showing thatkeybd_event()
would not return any value.byte bVk
was abyte
type parameter representing a virtual-key code of the given key that we wanted to simulate.byte bScan
was abyte
type parameter showing the hardware scan code of a key that must be simulated.uint dwFlags
was of typeunit
(unsigned integer), denoting the additional flags to control the key event.uint dwExtraInfo
was also of typeuint
(unsigned integer), used for extra information associated with the keystrokes.
We used the Add-Type
cmdlet to add the custom C# type (KeyboardFunctions
) to the current PowerShell session. This type was defined in the Wind32Functions
namespace and had the keybd_event()
function’s PInvoke declaration. We used various parameters with the Add-Type
cmdlet:
- We used the
-Name
parameter to mention custom C# type. - The
-Namespace
parameter was used to specify the namespace’s name. - The
-MemberDefinition
parameter was used to write the PInvoke signature variable ($pInvokeSignature
).
After that, we used the while
loop, which would always be true due to specifying the $true
condition. Inside the loop, we invoked the keybd_event()
method and passed four arguments which are explained below:
0x90
denoted the virtual-key code for the NUMLOCK key; you can find more virtual codes here.0
was the hardware scan code.0
indicated theKEYEVENTF_KEYDOWN
flag, which means the key was pressed.- The fourth argument was
0
because we didn’t want additional information about keystrokes.
We again invoked the keybd_event()
method with 0x90
, 0
, 2
, and 0
as first, second, third, and fourth arguments. All the same as the first call of the keybd_event()
function, excluding the third argument, which was 2
, denoting the KEYEVENTF_KEYUP
flag, means the key was released.
Then, we used the Start-Sleep
cmdlet to pause the script execution for 2
seconds, which we specified using the -Seconds
parameter. This way, we simulated the pressing & releasing of the NUMLOCK key every two seconds for unlimited time to prevent the PC from going into sleep mode.
The
keybd_event()
function is available but superseded in newer versions of Windows, so it is recommended to use alternatives; for instance,SendKeys()
andSendWait()
methods that we learned earlier in this article.
That’s all about powerShell script to keep screen active.
Sending a key to another application can be a useful technique for automating tasks, especially in a test environment or for creating macros. There are several ways to achieve this in C#, including using the SendKeys class, P/Invoke and Windows API, and using an automation library like UI Automation. In this article, we will explore the different methods to send a key to another application in C# and their respective pros and cons.
Method 1: SendKeys Class
To send a key to another application using the SendKeys
class in C#, you can follow these steps:
- First, add a reference to the
System.Windows.Forms
namespace.
using System.Windows.Forms;
- Use the
SendKeys
method to send a key to the active window.
This will send the «A» key to the active window.
- You can also send a combination of keys by using the «+» symbol to indicate the «Shift» key, «^» to indicate the «Control» key, and «%» to indicate the «Alt» key.
SendKeys.Send("^a"); // Sends Control+A
SendKeys.Send("%{F4}"); // Sends Alt+F4
- You can also send a key multiple times by using the «{n}» syntax, where «n» is the number of times to send the key.
SendKeys.Send("{BACKSPACE 5}"); // Sends Backspace 5 times
- If you need to send a key to a specific window, you can use the
SetForegroundWindow
method from theuser32.dll
library to bring the window to the front.
[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);
// Get the handle of the window you want to send keys to
IntPtr hWnd = FindWindow(null, "Window Title");
// Bring the window to the front
SetForegroundWindow(hWnd);
// Send the key to the window
SendKeys.Send("A");
These are just a few examples of how to use the SendKeys
class to send keys to another application in C#. For more information and options, you can refer to the official Microsoft documentation.
Method 2: P/Invoke and Windows API
To send a key to another application in C# using P/Invoke and Windows API, you can use the SendMessage
function from user32.dll library. This function sends the specified message to a window or windows. Here is how to do it:
- First, you need to define the constants and structures needed for the
SendMessage
function:
using System;
using System.Runtime.InteropServices;
public static class User32
{
public const int WM_KEYDOWN = 0x0100;
public const int WM_KEYUP = 0x0101;
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
}
- Next, you can use the
FindWindow
function from user32.dll to get the handle of the target window:
IntPtr handle = User32.FindWindow(null, "Window Title");
Replace «Window Title» with the title of the window you want to send the key to.
- After getting the handle of the target window, you can use the
SendMessage
function to send the key:
User32.SendMessage(handle, User32.WM_KEYDOWN, (IntPtr)Keys.A, IntPtr.Zero);
User32.SendMessage(handle, User32.WM_KEYUP, (IntPtr)Keys.A, IntPtr.Zero);
Replace Keys.A
with the key you want to send. The first call sends a key down message and the second call sends a key up message.
That’s it! You have successfully sent a key to another application using P/Invoke and Windows API in C#.
Method 3: UI Automation Library
To send a key to another application using the UI Automation Library in C#, you can follow these steps:
- Get the handle of the target application window using the
FindWindow
function from theuser32.dll
library.
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
IntPtr hWnd = FindWindow(null, "Target Application Title");
- Get the
AutomationElement
object of the target application window using theAutomationElement.FromHandle
method.
AutomationElement targetWindow = AutomationElement.FromHandle(hWnd);
- Find the target control within the target application window using the
AutomationElement.FindFirst
method.
Condition condition = new PropertyCondition(AutomationElement.NameProperty, "Target Control Name");
AutomationElement targetControl = targetWindow.FindFirst(TreeScope.Descendants, condition);
- Set the focus to the target control using the
AutomationElement.SetFocus
method.
targetControl.SetFocus();
- Send the key to the target control using the
SendKeys.SendWait
method.
SendKeys.SendWait("Key to Send");
Here’s the complete code example:
using System;
using System.Runtime.InteropServices;
using System.Windows.Automation;
using System.Windows.Forms;
public class KeySender
{
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
public static void SendKeyToTargetControl(string targetApplicationTitle, string targetControlName, string keyToSend)
{
IntPtr hWnd = FindWindow(null, targetApplicationTitle);
AutomationElement targetWindow = AutomationElement.FromHandle(hWnd);
Condition condition = new PropertyCondition(AutomationElement.NameProperty, targetControlName);
AutomationElement targetControl = targetWindow.FindFirst(TreeScope.Descendants, condition);
targetControl.SetFocus();
SendKeys.SendWait(keyToSend);
}
}
// Usage example:
KeySender.SendKeyToTargetControl("Target Application Title", "Target Control Name", "Key to Send");
Automatización, PowerShell
Introducction
Each key is represented by one or more characters. To specify a single keyboard character, use the character itself. For example, to represent the letter A, pass in the string «A» to the method. To represent more than one character, append each additional character to the one preceding it. To represent the letters A, B, and C, specify the parameter as «ABC».
The plus sign (+), caret (^), percent sign (%), tilde (~), and parentheses () have special meanings to SendKeys. To specify one of these characters, enclose it within braces ({}). For example, to specify the plus sign, use «{+}». To specify brace characters, use «{{}» and «{}}». Brackets ([ ]) have no special meaning to SendKeys, but you must enclose them in braces. In other applications, brackets do have a special meaning that might be significant when dynamic data exchange (DDE) occurs.
To specify characters that aren’t displayed when you press a key, such as ENTER or TAB, and keys that represent actions rather than characters, use the codes in the following table.
Key | Code |
---|---|
BACKSPACE | {BACKSPACE}, {BS}, or {BKSP} |
BREAK | {BREAK} |
CAPS LOCK | {CAPSLOCK} |
DEL or DELETE | {DELETE} or {DEL} |
DOWN ARROW | {DOWN} |
END | {END} |
ENTER | {ENTER}or ~ |
ESC | {ESC} |
HELP | {HELP} |
HOME | {HOME} |
INS or INSERT | {INSERT} or {INS} |
LEFT ARROW | {LEFT} |
NUM LOCK | {NUMLOCK} |
PAGE DOWN | {PGDN} |
PAGE UP | {PGUP} |
PRINT SCREEN | {PRTSC} (reserved for future use) |
RIGHT ARROW | {RIGHT} |
SCROLL LOCK | {SCROLLLOCK} |
TAB | {TAB} |
UP ARROW | {UP} |
F1 | {F1} |
F2 | {F2} |
F3 | {F3} |
F4 | {F4} |
F5 | {F5} |
F6 | {F6} |
F7 | {F7} |
F8 | {F8} |
F9 | {F9} |
F10 | {F10} |
F11 | {F11} |
F12 | {F12} |
F13 | {F13} |
F14 | {F14} |
F15 | {F15} |
F16 | {F16} |
Keypad add | {ADD} |
Keypad subtract | {SUBTRACT} |
Keypad multiply | {MULTIPLY} |
Keypad divide | {DIVIDE} |
To specify keys combined with any combination of the SHIFT, CTRL, and ALT keys, precede the key code with one or more of the following codes.
Key | Code |
---|---|
SHIFT | + |
CTRL | ^ |
ALT | % |
Examples
#Write some text [System.Windows.Forms.SendKeys]::SendWait(«Hi») #Press on Enter [System.Windows.Forms.SendKeys]::SendWait(«{ENTER}») #Repeat a key [System.Windows.Forms.SendKeys]::SendWait(«{RIGHT 5}») |
More information
- https://www.jesusninoc.com/system-windows-forms-sendkeys/
- https://www.jesusninoc.com/02/08/ejercicios-de-powershell-utilizar-sendkeys-en-powershell/
Publicado el día 5 de noviembre de 2015
CATEGORÍAS
Automatización, PowerShell