我已经将COM接口IPreviewHandler导入WinForms应用程序并使用它来显示各种类型文档的预览(我在注册表中查找相应预览处理程序的GUID,然后用于Activator.CreateInstance(guid)实例化特定的COM类.
这非常适用于绝大多数文件类型 - Office格式,PDF,视频等 - 但是,在我实例化"Microsoft Windows TXT预览处理程序"之后{1531d583-8375-4d3f-b5fb-d23bbd169f22},使用包含普通.txt文件的流初始化它,设置边界预览窗口,然后最后调用DoPreview(),我得到一个异常,无法使用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
}
Run Code Online (Sandbox Code Playgroud)
当我使用调试器时,Visual Studio Hosting Process崩溃了.没有调试器,应用程序崩溃而不触发AppDomain.UnHandledException或Application.ThreadException事件.
我真的不介意我无法使用这种技术预览纯文本文件(Office格式的工作预览处理程序等足以满足我的应用程序的要求),但我担心如果用户选择我的应用程序会无法控制地崩溃一个.txt文件.有什么方法可以捕捉到这个错误并优雅地处理它?更好的是,有什么方法可以克服它并使处理程序工作?
我无法让GetPreviewHandlerGUID()识别.txt文件,并且必须直接注入GUID.使用Project + Properties,Debug,tick启用非托管代码调试时,您可以看到出现了什么问题.
调试器现在将停止问题并显示
遇到`STATUS_STACK_BUFFER_OVERRUN
调用堆栈的顶部如下所示:
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
Run Code Online (Sandbox Code Playgroud)
问题出在StreamInCallback()函数中.它由RichTextBox调用,用于显示加载文件的预览(msftedit.dll).此回调函数中的代码有一个错误,它会破坏用于检测堆栈帧因缓冲区溢出而损坏的"canary".
这是微软采取的防止病毒通过缓冲区溢出注入自身的措施的一部分.Visual Studio中用于C/C++语言的/ GS编译选项.一旦检测到,CRT就会很快终止程序.这种情况发生时没有异常被提升,堆栈无法安全解开,因为它已被泄露.因此,CLR无法捕获异常.
此错误特定于TXT文件查看器.除了不使用它之外,你无能为力.将此错误报告给connect.microsoft.com可能没用,他们会将其关闭为"外部".这是一个微妙的提示,当您让非托管代码在您的程序中运行时会发生什么;)
| 归档时间: |
|
| 查看次数: |
3236 次 |
| 最近记录: |