IPreviewHandler引发不可复位异常 [英] IPreviewHandler throws uncatchable exception

查看:696
本文介绍了IPreviewHandler引发不可复位异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经导入COM接口 IPreviewHandler 到WinForms应用程序,并使用它来显示各种类型的文档的预览(我查找相应的预览的GUID处理程序,然后使用 Activator.CreateInstance(guid)来实例化特定的COM类。

I've imported the COM interface IPreviewHandler into a WinForms app and am using it to display previews for various types of documents (I look up the GUID of the appropriate preview handler in the registry, then use Activator.CreateInstance(guid) to instantiate the specific COM class.

> 这个工作>对于绝大多数的文件类型 - 办公文件格式,PDF,视频等 - 然而,在我实例化Microsoft Windows TXT预览处理程序 {1531d583-8375-4d3f -b5fb-d23bbd169f22} ,用包含普通.txt文件的流初始化,设置预览窗口的边界,然后调用 DoPreview(),我得到一个异常,不能使用try ... catch捕获:

This works wonderfully for the vast majority of file types - Office formats, PDFs, videos, etc - however, after I instantiate the "Microsoft Windows TXT Preview Handler" {1531d583-8375-4d3f-b5fb-d23bbd169f22}, initialise it with a stream containing an ordinary .txt file, set the bounds of the preview window and then finally call DoPreview(), I get an exception that cannot be caught using try...catch:

try {
    Type comType = Type.GetTypeFromCLSID(guid);
    object handler = Activator.CreateInstance(comType);

    if (handler is IInitializeWithStream) {
        Stream s = File.Open(filename, FileMode.Open);
        // this just passes the System.IO.Stream as the COM type IStream
        ((IInitializeWithStream)handler).Initialize(new StreamWrapper(s), 0);
    }
    else {
        throw new NotSupportedException();
    }

    RECT r = new RECT();
    r.Top = 0;
    r.Left = 0;
    r.Right = hostControl.Width;
    r.Bottom = hostControl.Height;

    ((IPreviewHandler)handler).SetWindow(hostControl.Handle, ref r);
    ((IPreviewHandler)handler).DoPreview();    // <-- crash occurs here
}
catch (Exception) {
    // this will never execute
}

当我使用调试器进行遍历时,Visual Studio主机进程崩溃。没有调试器,应用程序崩溃,而不触发 AppDomain.UnHandledException Application.ThreadException 事件。

When I step through with the debugger, the Visual Studio Hosting Process crashes. With no debugger, the application crashes without firing the AppDomain.UnHandledException or Application.ThreadException events.

我真的不介意我不能使用这种技术预览纯文本文件(Office格式的工作预览处理程序等足以满足我的应用程序的要求),但我关心如果用户选择一个.txt文件,有关我的应用程序崩溃不可控制。有什么办法我可以抓住这个错误,并优雅地处理吗?

I don't really mind that I can't preview plain text files using this technique (the working preview handlers for Office formats, etc are sufficient for my app's requirements), but I am concerned about having my app crash uncontrollably should the user select a .txt file. Is there any way I can catch this error and handle it gracefully? Better yet, is there some way I can overcome it and get the handler to work?

推荐答案

我无法获得GetPreviewHandlerGUID ()来识别一个.txt文件,并且必须直接注入GUID。您可以看到当您使用Project +属性,调试,打开启用非托管代码调试时出现什么问题。

I couldn't get the GetPreviewHandlerGUID() to recognize a .txt file and had to inject the GUID directly. You can see what goes wrong when you use Project + Properties, Debug, tick Enable unmanaged code debugging.

调试器现在停止问题并显示

The debugger will now stop on the problem and display


`遇到STATUS_STACK_BUFFER_OVERRUN

`STATUS_STACK_BUFFER_OVERRUN encountered

看起来像这样:

kernel32.dll!_UnhandledExceptionFilter@4()  + 0x1a368 bytes 
shell32.dll!___report_gsfailure()  + 0xc8 bytes 
shell32.dll!CRTFPreviewHandler::_StreamInCallback()  + 0x74 bytes   
msftedit.dll!CLightDTEngine::ReadPlainText()  + 0xed bytes  
msftedit.dll!CLightDTEngine::LoadFromEs()  + 0x202b3 bytes  
msftedit.dll!CTxtEdit::TxSendMessage()  + 0x1e25f bytes 
msftedit.dll!_RichEditWndProc@16()  + 0x13d bytes   

问题出现在StreamInCallback()函数中。它由RichTextBox调用,用于显示预览(msftedit.dll)以加载文件。这个回调函数中的代码有一个错误,它破坏了用来检测堆栈框架由于缓冲区溢出而被破坏的'canary'。

The problem is located in the StreamInCallback() function. It is called by the RichTextBox that's used to display the preview (msftedit.dll) to load the file. The code in this callback function has a bug, it destroys the 'canary' that's used to detect that the stack frame got corrupted because of a buffer overrun.

的微软为防止病毒通过缓冲区溢出而注入自己的措施。 Visual Studio中用于C / C ++语言的/ GS编译选项。一旦检测到,CRT非常迅速地终止程序。这发生没有异常得到提高,堆栈不能安全地解开,因为它被危害。因此,CLR无法捕获异常。

This is part of the counter-measures that Microsoft took to prevent viruses from injecting themselves by buffer overruns. The /GS compile option in Visual Studio for the C/C++ languages. Once detected, the CRT very swiftly terminates the program. This happens without an exception getting raised, the stack cannot safely be unwound because it was compromised. Accordingly, the CLR cannot catch the exception.

此错误特定于TXT文件查看器。除了不使用它,没有什么你能做的。将此错误报告给connect.microsoft.com可能没有用,他们会将其关闭为外部。这是一个微妙的提示,当你让非托管代码在你的程序中运行时会发生什么;)

This bug is specific to the TXT file viewer. There's nothing you can do about it other than not using it. Reporting this bug to connect.microsoft.com probably isn't useful, they'll close it as 'external'. This is otherwise a subtle hint what can happen when you let unmanaged code run inside your program ;)

这篇关于IPreviewHandler引发不可复位异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆