Reputation: 43
I have been trying to find the answer, but my research has not come up with much that is helpful to my situation. I am needing to emulate the Windows Key in my batch file that I am creating. This is to help me Maximize the window, as well as easily move it between monitors without the use of a mouse. The workstation this batch will autorun on, will not have access to a mouse or physical Keyboard.
This is the code I am working with.
@if (@CodeSection == @Batch) @then
@echo off
rem Use %SendKeys% to send keys to the keyboard buffer
set SendKeys=CScript //nologo //E:JScript "%~F0"
rem Start the other program in the same Window
Start "Progam"
rem the script only works if the application in question is the active window. Set a timer
timeout /t 10
rem use the tab key to move the cursor to the login and password inputs.
%SendKeys% "This would be the username{TAB}"
%SendKeys% "this would be the password{ENTER}"
rem I then have a timer to let the login happen
timeout /t 10
rem this where I am now trying to maximize and move the active window around.
goto :EOF
@end
// JScript section
var WshShell = WScript.CreateObject("WScript.Shell");
WshShell.SendKeys(WScript.Arguments(0));
Upvotes: 4
Views: 2103
Reputation: 12222
you can use http://nircmd.nirsoft.net/
nircmd sendkeypress key
Upvotes: 0
Reputation: 24466
Great question! Yeah, I had to battle this myself some time ago. I wanted to auto launch an application installed from the Microsoft Store on startup, and for reasons the easiest way for me to do that was to pin it to my Taskbar then simulate hitting ⊞+1 to launch it. I assume the case is now as it was back then, but there's no way to SendKeys()
the Windows meta key. But thanks to LandOfTheLostPass on reddit, I discovered an alternative to SendKeys()
: sending the keyboard scan code.
I modified the code from reddit to allow me to simulate pressing multiple keys, then release them. If I recall correctly, the code on reddit would only simulate press then release a single key at a time. I only modified the scan code function for multi-key combos. Re-examining the code now, it appears I might've broken the SendChars()
function. But I never used it anyway.
<# : win+1.bat -- Batch portion
@echo off & setlocal
powershell -window minimized -noprofile "iex (${%~f0} | out-string)"
goto :EOF
: end batch / begin PowerShell chimera #>
# https://www.reddit.com/r/PowerShell/comments/3qk9mc/keyboard_keypress_script/
Add-Type @"
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
public static class KBEmulator {
public enum InputType : uint {
INPUT_MOUSE = 0,
INPUT_KEYBOARD = 1,
INPUT_HARDWARE = 3
}
[Flags]
internal enum KEYEVENTF : uint
{
KEYDOWN = 0x0,
EXTENDEDKEY = 0x0001,
KEYUP = 0x0002,
SCANCODE = 0x0008,
UNICODE = 0x0004
}
[Flags]
internal enum MOUSEEVENTF : uint
{
ABSOLUTE = 0x8000,
HWHEEL = 0x01000,
MOVE = 0x0001,
MOVE_NOCOALESCE = 0x2000,
LEFTDOWN = 0x0002,
LEFTUP = 0x0004,
RIGHTDOWN = 0x0008,
RIGHTUP = 0x0010,
MIDDLEDOWN = 0x0020,
MIDDLEUP = 0x0040,
VIRTUALDESK = 0x4000,
WHEEL = 0x0800,
XDOWN = 0x0080,
XUP = 0x0100
}
// Master Input structure
[StructLayout(LayoutKind.Sequential)]
public struct lpInput {
internal InputType type;
internal InputUnion Data;
internal static int Size { get { return Marshal.SizeOf(typeof(lpInput)); } }
}
// Union structure
[StructLayout(LayoutKind.Explicit)]
internal struct InputUnion {
[FieldOffset(0)]
internal MOUSEINPUT mi;
[FieldOffset(0)]
internal KEYBDINPUT ki;
[FieldOffset(0)]
internal HARDWAREINPUT hi;
}
// Input Types
[StructLayout(LayoutKind.Sequential)]
internal struct MOUSEINPUT
{
internal int dx;
internal int dy;
internal int mouseData;
internal MOUSEEVENTF dwFlags;
internal uint time;
internal UIntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
internal struct KEYBDINPUT
{
internal short wVk;
internal short wScan;
internal KEYEVENTF dwFlags;
internal int time;
internal UIntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HARDWAREINPUT
{
internal int uMsg;
internal short wParamL;
internal short wParamH;
}
private class unmanaged {
[DllImport("user32.dll", SetLastError = true)]
internal static extern uint SendInput (
uint cInputs,
[MarshalAs(UnmanagedType.LPArray)]
lpInput[] inputs,
int cbSize
);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern short VkKeyScan(char ch);
}
internal static short VkKeyScan(char ch) {
return unmanaged.VkKeyScan(ch);
}
internal static uint SendInput(uint cInputs, lpInput[] inputs, int cbSize) {
return unmanaged.SendInput(cInputs, inputs, cbSize);
}
public static void SendScanCodeCombo(short[] scanCodes) {
lpInput[] KeyInputs = new lpInput[1];
lpInput KeyInput = new lpInput();
Enum[] actions = { KEYEVENTF.KEYDOWN, KEYEVENTF.KEYUP };
// Generic Keyboard Event
KeyInput.type = InputType.INPUT_KEYBOARD;
KeyInput.Data.ki.wScan = 0;
KeyInput.Data.ki.time = 0;
KeyInput.Data.ki.dwExtraInfo = UIntPtr.Zero;
// Press and release the correct key combination
foreach (KEYEVENTF action in actions) {
foreach (short scanCode in scanCodes) {
KeyInput.Data.ki.wVk = scanCode;
KeyInput.Data.ki.dwFlags = action;
KeyInputs[0] = KeyInput;
SendInput(1, KeyInputs, lpInput.Size);
}
}
return;
}
public static void SendChars(char[] keys) {
lpInput[] KeyInputs = new lpInput[1];
lpInput KeyInput = new lpInput();
Enum[] actions = { KEYEVENTF.KEYDOWN, KEYEVENTF.KEYUP };
// Generic Keyboard Event
KeyInput.type = InputType.INPUT_KEYBOARD;
KeyInput.Data.ki.wScan = 0;
KeyInput.Data.ki.time = 0;
KeyInput.Data.ki.dwExtraInfo = UIntPtr.Zero;
foreach (KEYEVENTF action in actions) {
foreach (char ch in keys) {
// Press the key
KeyInput.Data.ki.wVk = VkKeyScan(ch);
KeyInput.Data.ki.dwFlags = KEYEVENTF.KEYDOWN;
KeyInputs[0] = KeyInput;
SendInput(1, KeyInputs, lpInput.Size);
// Release the key
KeyInput.Data.ki.dwFlags = KEYEVENTF.KEYUP;
KeyInputs[0] = KeyInput;
SendInput(1, KeyInputs, lpInput.Size);
}
}
return;
}
}
"@ # end Add-Type
# Send LWin+1
[KBEmulator]::SendScanCodeCombo(@(0x5B, 0x31))
See Virtual-Key Codes on Microsoft Docs to find the scan codes for other keys.
By the way, the Windows API provides other ways to maximize and move windows without simulating keyboard shortcuts. (Please don't judge too harshly. I wrote that hack before learning how to write Batch + PowerShell hybrid scripts or to include .NET code in PowerShell.)
Upvotes: 2