IPreviewHandlerthrowsuncatchableexception我已经将COM接口IPreviewHandler导入到一个WinForms应用程序中,用它来显示各种类型文档的预览(我已经在注册表中注册了查一下GUID中相应的预览处理程序,然后使用Activator.CreateInstance(guid)来实例化特定的COM类。这适用于绝大多数文件类型——Office格式、PDF、视频等——但是,在我实例化“MicrosoftWindowsTXT预览处理程序”{1531d583-8375-4d3f-b5fb-d23bbd169f22}之后,使用包含的流对其进行初始化一个普通的.txt文件,设置预览窗口的边界,然后最后调用DoPreview(),我得到一个无法使用try...catch捕获的异常:try{TypecomType=Type.GetTypeFromCLSID(guid);对象处理程序=Activator.CreateInstance(comType);if(handlerisIInitializeWithStream){Streams=File.Open(filename,FileMode.Open);//这只是将System.IO.Stream作为COM类型传递IStream((IInitializeWithStream)handler).Initialize(newStreamWrapper(s),0);}else{抛出新的NotSupportedException();}RECTr=newRECT();r.Top=0;r.左=0;r.Right=hostControl.Width;r.Bottom=hostControl.Height;((IPreviewHandler)handler).SetWindow(hostControl.Handle,refr);((IPreviewHandler)处理程序).DoPreview();//<--此处发生崩溃}catch(Exception){//这将永远不会执行}当我单步执行调试器时,VisualStudio托管进程崩溃。如果没有调试器,应用程序将在不触发AppDomain.UnHandledException或Application.ThreadException事件的情况下崩溃。我真的不介意我不能使用这种技术预览纯文本文件(Office格式的工作预览处理程序等对我的应用程序来说已经足够),但我担心如果用户选择一个,我的应用程序将无法控制地崩溃.txt文件。有什么办法可以捕获这个错误并优雅地处理它吗?更好的是,有什么办法可以克服这个问题并让处理程序工作吗?我无法让GetPreviewHandlerGUID()识别.txt文件并且必须直接注入GUID。当您使用Project+Properties、Debug、tick启用非托管代码调试时,您可以看到出了什么问题。调试器现在将停止问题并显示遇到`STATUS_STACK_BUFFER_OVERRUN调用堆栈的顶部如下所示:kernel32.dll!_UnhandledExceptionFilter@4()+0x1a368字节shell32.dll!___report_gsfailure()+0xc8字节shell32.dll!CRTFPreviewHandler::_StreamInCallback()+0x74字节msftedit.dll!CLightDTEngine::ReadPlainText()+0xed字节msftedit.dll!CLightDTEngine::LoadFromEs()+0x202b3字节msftedit.dll!CTxtEdit::TxSendMessage()+0x1e25f字节msftedit。dll!_RichEdit16()+0x13d字节问题出在StreamInCallback()函数中。它由RichTextBox调用以显示加载文件(msftedit.dll)的预览。此回调函数中的代码有一个错误,该错误会破坏用于检测由于缓冲区溢出而导致的堆栈帧损坏的“金丝雀”。这是Microsoft为防止病毒通过缓冲区溢出注入自身而采取的措施的一部分。/GSVisualStudio中C/C++语言的编译选项。一旦检测到,CRT会很快终止程序。发生这种情况时不会引发异常,并且堆栈无法安全展开,因为它已经泄漏。因此,异常无法被CLR捕获。此错误特定于TXT文件查看器。除了不使用它之外,您无能为力。向connect.microsoft.com报告此错误可能没有用,他们会将其关闭为“外部”。这是一个微妙的提醒,提醒您让非托管代码在您的程序中运行时会发生什么;)我遇到了同样的问题,并且我能够通过在x64而不是AnyCPU上编译来使TXTPreviewHandler工作。我在Windows7(64位)上使用VisualStudio2010,因此如果您使用的是32位操作系统,则此答案不适用。在VisualStudio2010中,这不太可能,但可能是这里的问题-catch(Exception)只会捕获Exception类型的异常-尝试使用catchw/o任何类型的过滤。catch(Exceptionex){//正常日志记录等}catch{//除了System.Exception之外的类型的异常。我想我找到了解决这个问题的方法。问题是您正在创建的流正在被垃圾收集器或其他东西清理。如果您使用以下代码创建的流调用初始化方法,它应该可以工作:System.Runtime.InteropServices.ComTypes.IStreamstream;byte[]fileData=System.IO.File.ReadAllBytes(文件名);System.IntPtrhGlobal=System.Runtime.InteropServices.Marshal.AllocHGlobal(fileData.Length);System.Runtime.InteropServices.Marshal.Copy(fileData,0,hGlobal,fileData.Length);NativeMethods.CreateStreamOnHGlobal(hGlobal,false,outstream);//[DllImport("ole32.dll")]//internalstaticexternintCreateStreamOnHGlobal(IntPtrhGlobal,boolfDeleteOnRelease,outIStreamppstm);我在Windows窗体应用程序中使用上面的代码显式设置为32位(x86)并在线程单元模式下运行。感谢SherlockHomes(http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.interop/2010-09/msg00003.html)以上是C#学习教程:IPreviewHandlerthrowsuncatchable如果异常分享的所有内容对您有用,需要了解更多C#学习教程,希望您多多关注——本文整理自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
