using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
///
///
///
public class WindowsAPI
{
///
///
///
public const uint WM_KEYDOWN = 0x100;
///
///
///
public const uint WM_KEYUP = 0x101;
///
///
///
public const uint WM_LBUTTONDOWN = 0x201;
///
///
///
public const uint WM_LBUTTONUP = 0x202;
public const uint WM_CHAR = 0x102;
///
///
///
public const int MK_LBUTTON = 0x01;
///
///
///
public const int VK_RETURN = 0x0d;
public const int VK_ESCAPE = 0x1b;
///
///
///
public const int VK_TAB = 0x09;
///
///
///
public const int VK_LEFT = 0x25;
///
///
///
public const int VK_UP = 0x26;
///
///
///
public const int VK_RIGHT = 0x27;
///
///
///
public const int VK_DOWN = 0x28;
///
///
///
public const int VK_F5 = 0x74;
///
///
///
public const int VK_F6 = 0x75;
///
///
///
public const int VK_F7 = 0x76;
///
/// The GetForegroundWindow function returns a handle to the foreground window.
///
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("kernel32.dll")]
public static extern uint GetCurrentThreadId();
[DllImport("user32.dll", SetLastError = true)]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("user32.dll")]
public static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
[Out()] byte[] lpBuffer,
int dwSize,
out int lpNumberOfBytesRead
);
public static void SwitchWindow(IntPtr windowHandle)
{
if (GetForegroundWindow() == windowHandle)
return;
IntPtr foregroundWindowHandle = GetForegroundWindow();
uint currentThreadId = GetCurrentThreadId();
uint temp;
uint foregroundThreadId = GetWindowThreadProcessId(foregroundWindowHandle, out temp);
AttachThreadInput(currentThreadId, foregroundThreadId, true);
SetForegroundWindow(windowHandle);
AttachThreadInput(currentThreadId, foregroundThreadId, false);
while (GetForegroundWindow() != windowHandle)
{
}
}
///
///
///
///
///
///
///
///
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
///
///
///
///
///
///
///
///
[DllImport("User32.Dll", EntryPoint = "PostMessageA")]
public static extern bool PostMessage(IntPtr hWnd, uint msg, int wParam, int lParam);
///
///
///
///
///
[DllImport("user32.dll")]
public static extern byte VkKeyScan(char ch);
[DllImport("user32.dll")]
public static extern uint MapVirtualKey(uint uCode, uint uMapType);
///
///
///
///
///
public static IntPtr FindWindow(string name)
{
Process[] procs = Process.GetProcesses();
foreach (Process proc in procs)
{
if (proc.MainWindowTitle == name)
{
return proc.MainWindowHandle;
}
}
return IntPtr.Zero;
}
public static void Main()
{
int procesId = YourEnumerateClass.Enum16BitProcesses();
Process processes = Process.GetProcessById( procesId );
if (processes == null)
throw new Exception("Could not find the Warhammer process; is Warhammer running?");
IntPtr WindowHandle = processes.MainWindowHandle;
PressKey('a', true);
System.Threading.Thread.Sleep(100);
PressKey('a', false);
}
[DllImport("user32.dll")]
public static extern IntPtr SetFocus(IntPtr hWnd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
///
///
///
///
///
///
public static int MakeLong(int low, int high)
{
return (high << 16) | (low & 0xffff);
}
public static void KeyDown(ushort scanCode)
{
INPUT[] inputs = new INPUT[1];
inputs[0].type = WindowsAPI.INPUT_KEYBOARD;
inputs[0].ki.dwFlags = 0;
inputs[0].ki.wScan = (ushort)(scanCode & 0xff);
uint intReturn = WindowsAPI.SendInput(1, inputs, System.Runtime.InteropServices.Marshal.SizeOf(inputs[0]));
if (intReturn != 1)
{
throw new Exception("Could not send key: " + scanCode);
}
}
public static void KeyUp(ushort scanCode)
{
INPUT[] inputs = new INPUT[1];
inputs[0].type = WindowsAPI.INPUT_KEYBOARD;
inputs[0].ki.wScan = scanCode;
inputs[0].ki.dwFlags = WindowsAPI.KEYEVENTF_KEYUP;
uint intReturn = WindowsAPI.SendInput(1, inputs, System.Runtime.InteropServices.Marshal.SizeOf(inputs[0]));
if (intReturn != 1)
{
throw new Exception("Could not send key: " + scanCode);
}
}
public static void PressKey(char ch, bool press)
{
byte vk = WindowsAPI.VkKeyScan(ch);
ushort scanCode = (ushort)WindowsAPI.MapVirtualKey(vk, 0);
if (press)
KeyDown(scanCode);
else
KeyUp(scanCode);
}
[DllImport("User32.dll")]
public static extern uint SendInput(uint numberOfInputs, [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] INPUT[] input, int structSize);
[DllImport("user32.dll")]
public static extern IntPtr GetMessageExtraInfo();
public const int INPUT_MOUSE = 0;
public const int INPUT_KEYBOARD = 1;
public const int INPUT_HARDWARE = 2;
public const uint KEYEVENTF_EXTENDEDKEY = 0x0001;
public const uint KEYEVENTF_KEYUP = 0x0002;
public const uint KEYEVENTF_UNICODE = 0x0004;
public const uint KEYEVENTF_SCANCODE = 0x0008;
public const uint XBUTTON1 = 0x0001;
public const uint XBUTTON2 = 0x0002;
public const uint MOUSEEVENTF_MOVE = 0x0001;
public const uint MOUSEEVENTF_LEFTDOWN = 0x0002;
public const uint MOUSEEVENTF_LEFTUP = 0x0004;
public const uint MOUSEEVENTF_RIGHTDOWN = 0x0008;
public const uint MOUSEEVENTF_RIGHTUP = 0x0010;
public const uint MOUSEEVENTF_MIDDLEDOWN = 0x0020;
public const uint MOUSEEVENTF_MIDDLEUP = 0x0040;
public const uint MOUSEEVENTF_XDOWN = 0x0080;
public const uint MOUSEEVENTF_XUP = 0x0100;
public const uint MOUSEEVENTF_WHEEL = 0x0800;
public const uint MOUSEEVENTF_VIRTUALDESK = 0x4000;
public const uint MOUSEEVENTF_ABSOLUTE = 0x8000;
}
[StructLayout(LayoutKind.Sequential)]
public struct MOUSEINPUT
{
int dx;
int dy;
uint mouseData;
uint dwFlags;
uint time;
IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
public struct KEYBDINPUT
{
public ushort wVk;
public ushort wScan;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
public struct HARDWAREINPUT
{
uint uMsg;
ushort wParamL;
ushort wParamH;
}
[StructLayout(LayoutKind.Explicit)]
public struct INPUT
{
[FieldOffset(0)]
public int type;
[FieldOffset(4)] //*
public MOUSEINPUT mi;
[FieldOffset(4)] //*
public KEYBDINPUT ki;
[FieldOffset(4)] //*
public HARDWAREINPUT hi;
}
public class YourEnumerateClass
{
public static void Enum16BitProcesses()
{
// create a delegate for the callback function
ProcessTasksExDelegate procTasksDlgt =
new ProcessTasksExDelegate(YourEnumerateClass.ProcessTasksEx);
// this part is the easy way of getting NTVDM procs
foreach (var ntvdm in Process.GetProcessesByName("ntvdm"))
{
Console.WriteLine("ntvdm id = {0}", ntvdm.Id);
int apiRet = VDMEnumTaskWOWEx(ntvdm.Id, procTasksDlgt, IntPtr.Zero);
Console.WriteLine("EnumTaskWOW returns {0}", apiRet);
}
}
// declaration of API function callback
public delegate bool ProcessTasksExDelegate(
int ThreadId,
IntPtr hMod16,
IntPtr hTask16,
IntPtr ptrModName,
IntPtr ptrFileName,
IntPtr UserDefined
);
// the actual function that fails on Vista so far
[DllImport("VdmDbg.dll", SetLastError = false, CharSet = CharSet.Auto)]
public static extern int VDMEnumTaskWOWEx(
int processId,
ProcessTasksExDelegate TaskEnumProc,
IntPtr lparam);
// the actual callback function, on Vista never gets called
public static bool ProcessTasksEx(
int ThreadId,
IntPtr hMod16,
IntPtr hTask16,
IntPtr ptrModName,
IntPtr ptrFileName,
IntPtr UserDefined
)
{
// using PtrToStringAnsi, based on Matt's comment, if it fails, try PtrToStringAuto
string filename = Marshal.PtrToStringAnsi(ptrFileName);
Console.WriteLine("Filename of WOW16 process: {0}", filename);
return false; // false continues enumeration
}
}