Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Process.Start()时,WindowsForm鼠标会触发两次_C#_Wpf_Winforms_Mouseup - Fatal编程技术网

C# 使用Process.Start()时,WindowsForm鼠标会触发两次

C# 使用Process.Start()时,WindowsForm鼠标会触发两次,c#,wpf,winforms,mouseup,C#,Wpf,Winforms,Mouseup,在我的Windows窗体应用程序中,如果单击其中一个项目,我必须打开一个带有特定文件夹的新资源管理器窗口。我现在正在监听MouseUp事件(因为我已经有一些点击检测,我需要点击坐标),如果我在之前打开一个新的浏览器窗口 private void listView1_MouseUp(object sender, MouseEventArgs e) { Process.Start(@"C:\"); } 它会打开浏览器窗口两次。它肯定与进程有关

在我的Windows窗体应用程序中,如果单击其中一个项目,我必须打开一个带有特定文件夹的新资源管理器窗口。我现在正在监听MouseUp事件(因为我已经有一些点击检测,我需要点击坐标),如果我在之前打开一个新的浏览器窗口

private void listView1_MouseUp(object sender, MouseEventArgs e)
    {
        Process.Start(@"C:\");
    }
它会打开浏览器窗口两次。它肯定与
进程有关
是否有某种方法可以将事件标记为已处理或忽略第二次执行?

这是一个重入错误,与在代码中使用DoEvents()时出现的错误非常相似。但在这种情况下,这个bug是内置在操作系统中的。解决这个问题的工具是Explorer,它在代码中有一个非常不寻常的激活模式。当您查看Process.Start()的返回值时,可以看到它是
null
。当Process.Start()未实际启动进程时发生

通过使用只在第二次命中的条件断点,可以看到正在运行的bug。在启用非托管调试和符号服务器的情况下,调用堆栈如下所示:

WindowsFormsApp1.exe!WindowsFormsApp1.Form1.listView1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) Line 19 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.OnMouseUp(System.Windows.Forms.MouseEventArgs e) Line 9140    C#
System.Windows.Forms.dll!System.Windows.Forms.ListView.WndProc(ref System.Windows.Forms.Message m) Line 6298    C#
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) Line 14236  C#
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) Line 14291    C#
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) Line 780 C#
[Native to Managed Transition]  
user32.dll!__InternalCallWinProc@20()  Unknown
user32.dll!UserCallWinProcCheckWow()    Unknown
user32.dll!CallWindowProcW()    Unknown
comctl32.dll!_CallNextSubclassProc@20()    Unknown
comctl32.dll!_CallNextSubclassProc@20()    Unknown
comctl32.dll!_MasterSubclassProc@16()  Unknown
user32.dll!__InternalCallWinProc@20()  Unknown
user32.dll!UserCallWinProcCheckWow()    Unknown
user32.dll!DispatchMessageWorker()  Unknown
user32.dll!_DispatchMessageW@4()   Unknown
shell32.dll!SHProcessMessagesUntilEventsEx(struct HWND__ *,void * *,unsigned long,unsigned long,unsigned long,unsigned long)    Unknown
shell32.dll!CShellExecute::_RunThreadMaybeWait(bool)    Unknown
shell32.dll!CShellExecute::ExecuteNormal(struct _SHELLEXECUTEINFOW *)   Unknown
shell32.dll!ShellExecuteNormal(struct _SHELLEXECUTEINFOW *) Unknown
shell32.dll!_ShellExecuteExW@4()   Unknown
System.ni.dll!71db9903()    Unknown
[Frames below may be incorrect and/or missing, native debugger attempting to walk managed call stack]   
[Managed to Native Transition]  
System.dll!System.Diagnostics.ShellExecuteHelper.ShellExecuteFunction() Unknown
System.dll!System.Diagnostics.ShellExecuteHelper.ShellExecuteOnSTAThread()  Unknown
System.dll!System.Diagnostics.Process.StartWithShellExecuteEx(System.Diagnostics.ProcessStartInfo startInfo)    Unknown
System.dll!System.Diagnostics.Process.Start()   Unknown
System.dll!System.Diagnostics.Process.Start(System.Diagnostics.ProcessStartInfo startInfo)  Unknown
System.dll!System.Diagnostics.Process.Start(string fileName)    Unknown
WindowsFormsApp1.exe!WindowsFormsApp1.Form1.listView1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) Line 19 C#
shProcessMessageSunTileEventSex()函数是作恶者,拼写“DoEvents”并实现“maybe wait”的漫长过程,它会导致重新输入Winforms应用程序的dispatcher循环。再次检测MouseUp条件并重新触发事件处理程序

您无法修复操作系统,但解决方案是导致重入问题的事件处理程序的通用解决方案,您可以使用BeginInvoke()完全延迟棘手的代码,以便它在事件处理后立即运行。像这样:

private void listView1_MouseUp(object sender, MouseEventArgs e) {
    this.BeginInvoke(new Action(() => {
        Process.Start(@"C:\");
    }));
}

尝试单步遍历代码,看看它是否运行了两次代码?嗨,Balic,刚刚尝试过。如果我只有一个控制台。WriteLine(e.Button);我得到两次输出。如果我在方法内部设置断点,那么它只执行一次。也许焦点转移到新打开的资源管理器窗口,然后很快又回来了?但那只是猜测。嗯,奇怪。您是否尝试过使用MouseClick事件,而不是MouseUp,只是一个想法……它看起来可能是一个具有multiselect属性的bug是的,使用MouseClick它确实有效,并且只触发一次。但是在实际的应用程序中,我真的很想使用鼠标,因为当用户在列表框中单击并执行操作时,会发生一些事情。但如果没有其他方法,这将是备用解决方案。非常感谢您的深入解释和有效解决方案!代码正在按预期工作,我学到了一些东西;-)