So, I have a strange problem. I'm making a WPF app that moves the mouse around. I have the following bit of code for this:
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
public int X;
public int Y;
public static implicit operator Point(POINT point)
{
return new Point(point.X, point.Y);
}
}
[DllImport("user32.dll")]
private static extern bool GetCursorPos(out POINT lpPoint);
[DllImport("user32.dll", EntryPoint = "SetCursorPos")]
private static extern void SetCursorPos(int X, int Y);
private static Random random = new Random(DateTime.Now.Millisecond);
public static Point GetMousePosition()
{
GetCursorPos(out POINT lpPoint);
return lpPoint;
}
public static void MoveMouse(int x, int y, int tolerance = 10)
{
tolerance = Math.Max(0, tolerance);
int startX = GetMousePosition().X;
int startY = GetMousePosition().Y;
int finalX = random.Next(x - tolerance, x + tolerance + 1);
int finalY = random.Next(y - tolerance, y + tolerance + 1);
int diffX = finalX - startX;
int diffY = finalY - startY;
double time = Math.Max(1, Math.Max(Math.Abs(diffX), Math.Abs(diffY)) / (5 + random.NextDouble()));
double deltaX = diffX / time;
double deltaY = diffY / time;
for (int i = 1; i <= time; i++)
{
SetCursorPos((int)(startX + deltaX * i), (int)(startY + deltaY * i));
}
}
Basically long story short, call MoveMouse() with an x,y coordinate and it'll move the mouse to that point on screen ± [tolerance] pixels.
If I run it out of visual studio directly, with debugger attached, everything works as expected. However, if ran without the debugger, the mouse actually moves 2-3 times slower. I'd have to throw in a Thread.Sleep(1); inside the for loop just to match what it does in release mode. And then, if I leave the delay in there, it actually goes even slower in production! If I run the app stand-alone, observing its usual slowness, and then manually attach the debugger to it later, it suddenly becomes fast.
What gives? How can I make it go as fast in "production" as it does in debug?
To clarify: the "debug" vs "release" configuration doesn't actually make a difference. It's only different when the debugger is attached.
A-HA! I figured it out. On a wild hunch, I decided to dig up some time period shenanigans that I had some vague experience using a long time ago.
I added
[DllImport("winmm.dll", EntryPoint = "timeBeginPeriod", SetLastError = true)]
public static extern uint TimeBeginPeriod(uint uMilliseconds);
[DllImport("winmm.dll", EntryPoint = "timeEndPeriod", SetLastError = true)]
public static extern uint TimeEndPeriod(uint uMilliseconds);
and then wrapped the mouse moving code in
TimeBeginPeriod(1);
and
TimeEndPeriod(1);
This normalized the speeds across all possible run modes, solving my problem. Though now I'm also left confused as to why the debugger is interfering with this stuff. :/ Oh well, for the time being I'm satisfied and that can be another adventure for another time I guess, if it ever becomes relevant again.