C# AccessViolationException 非托管方法
如果鼠标下方的像素颜色具有特定颜色,我的程序会在 Windows 窗体中自动单击。现在的问题是,有时,也许在程序运行一个小时后,或者可能在程序运行 5 小时后(并且工作看起来完全正常),整个系统 (OS) 崩溃了。有时,我能够捕获 AccessViolationException。 我很确定崩溃与我必须调用的非托管方法有关,这些方法用于单击鼠标并获取屏幕像素的颜色。但我根本无法弄清楚出了什么问题。我使用以下代码进行鼠标单击:
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
static extern void mouse_event(uint dwFlags, uint dx, uint dy,
uint dwData, UIntPtr dwExtraInfo);
private const uint MOUSEEVENTF_LEFTDOWN = 0x02;
private const uint MOUSEEVENTF_LEFTUP = 0x04;
public void DoMouseClick()
{
//Call the imported function with the cursor's current position
uint X = (uint)Cursor.Position.X;
uint Y = (uint)Cursor.Position.Y;
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, X, Y, 0, UIntPtr.Zero);
}
为了获取像素的颜色,我使用以下代码:
[DllImport("user32.dll")]
static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("user32.dll")]
static extern Int32 ReleaseDC(IntPtr hwnd, IntPtr hdc);
[DllImport("gdi32.dll")]
static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);
static public System.Drawing.Color GetPixelColor(int x, int y)
{
IntPtr hdc = GetDC(IntPtr.Zero);
uint pixel = GetPixel(hdc, x, y);
ReleaseDC(IntPtr.Zero, hdc);
Color color = Color.FromArgb((int)(pixel & 0x000000FF),
(int)(pixel & 0x0000FF00) >> 8,
(int)(pixel & 0x00FF0000) >> 16);
return color;
}
两种方法大多是从互联网复制粘贴的。我在 Windows 窗体中使用了前面提到的这些东西。 Forms.Timer 一直在运行,不知道这是否重要...在 64 位 Windows 上运行它,但该程序是针对目标 x86 编译的。
编辑:我非常确定非托管方法负责的原因是 AccessViolationException 的堆栈跟踪的外观(“bei”=“at”):
bei System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
bei System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
bei System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
bei System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
bei System.Windows.Forms.Application.Run(Form mainForm)
bei McDonaldsVote.Program.Main(String[] args) in C:\Users\Chris\Documents\Visual Studio 2008\Projects\McDonaldsVote\McDonaldsVote\Program.cs:Zeile 22.
My program does automated clicks in a Windows Form, if the color of the pixel under the mouse has a specific color. Now the problem is that sometimes, maybe after an hour, or maybe after 5 hours of the program running (and working seemingly totally fine), the complete system (OS) crashes. Sometimes, I'm able to catch an AccessViolationException.
I'm pretty sure the crashing has got to do with the unmanaged methods I have to call for clicking the mouse and getting the color of a screen pixel. But I can't for the hell of it figure out what's wrong. I use the following code for mouse clicks:
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
static extern void mouse_event(uint dwFlags, uint dx, uint dy,
uint dwData, UIntPtr dwExtraInfo);
private const uint MOUSEEVENTF_LEFTDOWN = 0x02;
private const uint MOUSEEVENTF_LEFTUP = 0x04;
public void DoMouseClick()
{
//Call the imported function with the cursor's current position
uint X = (uint)Cursor.Position.X;
uint Y = (uint)Cursor.Position.Y;
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, X, Y, 0, UIntPtr.Zero);
}
And for getting the color of a pixel, I use this:
[DllImport("user32.dll")]
static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("user32.dll")]
static extern Int32 ReleaseDC(IntPtr hwnd, IntPtr hdc);
[DllImport("gdi32.dll")]
static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);
static public System.Drawing.Color GetPixelColor(int x, int y)
{
IntPtr hdc = GetDC(IntPtr.Zero);
uint pixel = GetPixel(hdc, x, y);
ReleaseDC(IntPtr.Zero, hdc);
Color color = Color.FromArgb((int)(pixel & 0x000000FF),
(int)(pixel & 0x0000FF00) >> 8,
(int)(pixel & 0x00FF0000) >> 16);
return color;
}
Both methods are mostly copy-pasted from the internet. I use this stuff as mentioned before in Windows Forms. A Forms.Timer is running the whole time, don't know if that matters... running this on a 64 bit Windows, the program is compiled for target x86 though.
edit: The reason I'm pretty sure the unmanaged methods are responsible is the way this Stack Trace of the AccessViolationException looks ("bei"="at"):
bei System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
bei System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
bei System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
bei System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
bei System.Windows.Forms.Application.Run(Form mainForm)
bei McDonaldsVote.Program.Main(String[] args) in C:\Users\Chris\Documents\Visual Studio 2008\Projects\McDonaldsVote\McDonaldsVote\Program.cs:Zeile 22.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论