我有一个WPF MVVM应用程序。它使用.NET Framework 3.5,并且使用C#编程。
我正在尝试调试我的应用程序。通过按F5键,可以直接从VS IDE以调试模式启动它。从Visual Studio 2008 IDE启动后,当我的应用程序崩溃时,VS不会破坏该应用程序以查看引起该错误的代码,它仅显示对话框,并带有vshost32.exe停止工作的消息。没有出现异常名称和调用堆栈,因此很难检测到导致此行为的代码行。
从VS IDE中的“调试”->“异常”菜单中,我不知道必须检查哪个异常才能使程序停止在崩溃时导致错误的行上。
我还在下面的app.xaml.cs中完成了捕获未处理的异常的操作,如here和here所述,但是在我的情况下没有抛出任何异常:
Log log = Log.GetInstance();
public App()
{
Startup += new StartupEventHandler(App_Startup); // Can be called from XAML
DispatcherUnhandledException += App_DispatcherUnhandledException; //Example 2
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; //Example 4
System.Windows.Forms.Application.ThreadException += WinFormApplication_ThreadException; //Example 5
}
void App_Startup(object sender, StartupEventArgs e)
{
//Here if called from XAML, otherwise, this code can be in App()
AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException; // Example 1
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; // Example 3
}
// Example 1
void CurrentDomain_FirstChanceException(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e)
{
MessageBox.Show("1. CurrentDomain_FirstChanceException");
//ProcessError(e.Exception); - This could be used here to log ALL errors, even those caught by a Try/Catch block
}
// Example 2
void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
MessageBox.Show("2. App_DispatcherUnhandledException");
log.ProcessError(e.Exception);
e.Handled = true;
}
// Example 3
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
MessageBox.Show("3. CurrentDomain_UnhandledException");
var exception = e.ExceptionObject as Exception;
log.ProcessError(exception);
if (e.IsTerminating)
{
//Now is a good time to write that critical error file!
MessageBox.Show("Goodbye world!");
}
}
// Example 4
void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
MessageBox.Show("4. TaskScheduler_UnobservedTaskException");
log.ProcessError(e.Exception);
e.SetObserved();
}
// Example 5
void WinFormApplication_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
MessageBox.Show("5. WinFormApplication_ThreadException");
log.ProcessError(e.Exception);
}
在上述异常处理程序中,NET Framework 3.5不支持TaskScheduler.UnobservedTaskException,因为它使用名称空间System.Threading.Tasks NET Framework 3.5中没有该功能,只有NET Framework 4.0及更高版本才支持它,因此我仅实现了其他功能。
我还发现了其他有趣的文章,如下所示:
尽管实现了以上所有5个异常处理程序(在我的情况下,除外TaskScheduler_UnobservedTaskException),但是当我的WPF应用程序崩溃并显示vshost32.exe停止工作的消息时,没有实现5个异常处理程序,因此我猜想是另外一种抛出异常,但是哪个?我认为使用这5个异常处理程序将捕获所有WPF和winform异常(如果在wpf中使用winforms),但是我发现并非如此。
其他信息: 该WPF应用程序使用第三方DLL打印PDF。这是PDFiumViewer:
此库与其页面中所述的Windows 8完全兼容(我正在使用Windows 8 x64)。
我按照here的说明使用它来打印PDF:
public bool PrintPDF(
string printer,
string paperName,
string filename,
int copies)
{
try {
// Create the printer settings for our printer
var printerSettings = new PrinterSettings {
PrinterName = printer,
Copies = (short)copies,
};
// Create our page settings for the paper size selected
var pageSettings = new PageSettings(printerSettings) {
Margins = new Margins(0, 0, 0, 0),
};
foreach (PaperSize paperSize in printerSettings.PaperSizes) {
if (paperSize.PaperName == paperName) {
pageSettings.PaperSize = paperSize;
break;
}
}
// Now print the PDF document
using (var document = PdfDocument.Load(filename)) {
using (var printDocument = document.CreatePrintDocument()) {
printDocument.PrinterSettings = printerSettings;
printDocument.DefaultPageSettings = pageSettings;
printDocument.PrintController = new StandardPrintController();
printDocument.Print();
}
}
return true;
} catch {
return false;
}
}
此库使用{@ {3}}中的本机PDFium库,并且需要该库。我正在使用以下版本:PdfiumViewer.Native.x86.v8-xfa,因为我正在使用Windows 8,并且我不希望支持Windows XP。此外,在我的Visual Studio 2008项目中,我有两个文件夹x86和x64,每个文件夹中都有正确的版本PdfiumViewer.Native.x86.v8-xfa和PdfiumViewer.Native.x86_64.v8-xfa,因为有必要将这些库用于放在这些文件夹(或根项目文件夹)中以找到它们并正常工作。
我使用nuget包和Visual Studio 2015获得了PDFiumViewer和本机PDFium库,因为Visual Studio 2008不支持nuget。一旦获得了这些DLL,就可以引用(PDFiumViewer)并将其复制(PDFium库)到我的Visual Studio 2008项目中,并将它们放在正确的文件夹中。
最后,我必须说这个问题不仅是在调试时在Visual Studio 2008 IDE中引起的,而且在正常运行应用程序时(即在Visual Studio调试器之外)也发生了。此外,“ vshost32.exe停止工作”异常有时会很快出现或稍后出现。
另外,在添加此第三方和本机库(PDFiumViewer和PDFium库)之前也没有发生此问题,因此这可能是问题所在,因为PDFiumViewer使用dllimport语句调用非托管DLL来从PDFium导入本机方法,例如:< / p>
private static class Imports
{
[DllImport("pdfium.dll")]
public static extern void FPDF_AddRef();
[DllImport("pdfium.dll")]
public static extern void FPDF_Release();
[DllImport("pdfium.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr FPDF_LoadCustomDocument([MarshalAs(UnmanagedType.LPStruct)]FPDF_FILEACCESS access, string password);
[DllImport("pdfium.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr FPDF_LoadMemDocument(SafeHandle data_buf, int size, string password);
// And some other ones, not posted here to simplify.
}