Unfortunately, [System.Windows.Forms.SendKeys]
does not directly support sending sending keystrokes based on the Windows key.
To do so, a P/Invoke solution is required, which requires on-demand compilation of C# code via the Add-Member
cmdlet, adapted from this answer:
Add-Type -ReferencedAssemblies System.Windows.Forms -UsingNamespace System.Windows.Forms -Namespace demo -Name SendKeyExt -MemberDefinition @'
[DllImport("user32.dll")]
private static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
private const int KEYEVENTF_EXTENDEDKEY = 1;
private const int KEYEVENTF_KEYUP = 2;
public static void SendKeysWithWinKey(string keys = null) {
keybd_event((byte) Keys.LWin, 0, KEYEVENTF_EXTENDEDKEY, 0);
if (!String.IsNullOrEmpty(keys)) { SendKeys.SendWait(keys.ToLowerInvariant()); }
keybd_event((byte) Keys.LWin, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
}
'@
The above defines type [demo.SendKeyExt]
, whose static ::SendKeysWithWinKey()
method:
accepts a string describing a key combination as supported by [System.Windows.Forms.SendKeys]::Send/SendWait
, e.g, "{up}"
and sends that key combination - using .SendWait()
, for technical reasons - while programmatically holding down the Windows key (note that the key combination is converted to lowercase for technical reasons; it ensures that letters such as X
are correctly recognized as to be combined with the Windows key).
Note that you pay a performance penalty for the ad-hoc compilation performed by Add-Member
, but only once per session.
Once the type is defined, you can use it as follows:
# Maximize the current window.
# Same as pressing WinKey+Up-Arrow
[demo.SendKeyExt]::SendKeysWithWinKey('{up}')
# Maximize the current window only *vertically* (+ == Shift)
# Same as pressing WinKey+Shift+Up-Arrow
[demo.SendKeyExt]::SendKeysWithWinKey('+{up}')