I'm maintaining a legacy C# Winform application, using .NET 4.0 framework. The application works fine, but occasionally due to bugs in the application, the application will fail to work properly when the the application creates invalid data in the database.
At certain points, we bind the (invalid/corrupt) data to a datagrid, which causes numerous errors when it attempts to map a null column to a datagrid column.
An exception of type 'System.InvalidCastException' occurred in mscorlib.dll but was not handled in user code
Additional information: Object cannot be cast from DBNull to other types.
As well as
An exception of type 'System.Reflection.TargetInvocationException' occurred in System.Windows.Forms.dll but was not handled in user code
The errors cause a nice popup to show when run under the Visual Studio debugger detailing the error as well as allowing me to see the line where the error occurred.
In this particular case, I know what the issue is, so I can easily correct it. However, this class of error occurs too-often in other parts of the application, so it's not always obvious what is happening, and my users don't always provide good error reports. To try and combat this, I'd like to add logging to the application (using log4net), which works in our situation as each user has their own copy of the application so I can obtain per-user logs after the fact.
Using hints from stackoverflow as well as various other sources, I found a lot of good information on setting up handlers for these unhandled exceptions. Unfortunately, my handlers are not being called for the majority of the 'unhandled' exceptions.
The mostly relevant parts of the application are below:
static class Program {
private static readonly ILog log = LogManager.GetLogger("Main");
static void Main() {
// Add some error handlers which log error data to the logfile
//
// For UI events (set the unhandled exception mode to force all Windows Forms
// errors to go through our handler)
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.ThreadException += new ThreadExceptionEventHandler(delegate(object s, ThreadExceptionEventArgs e) {
ExceptionLogger(e.Exception);
});
// Non-UI thread exceptions
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(delegate(object sender, UnhandledExceptionEventArgs e) {
ExceptionLogger(e.ExceptionObject as Exception);
});
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
log.Debug("Starting Application");
Application.Run(mainForm = new MainForm());
}
private static void ExceptionLogger(Exception e) {
log.Error("Unhandled Error", e);
string errorMsg = "An application error occurred. Please contact the administrator with the following information:\n\n";
errorMsg = errorMsg + e.Message + "\n\nStack Trace:\n" + e.StackTrace;
if (MessageBox.Show(errorMsg, "TLMS Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop) == DialogResult.Abort)
Application.Exit();
}
The Exception handler seems to work if the errors occur directly in my own code, but the handler is not called if/when the errors occur directly in the .NET libraries, and I want the handler called for all Unhandled exceptions, including those outside of code I've written.
Being able to use the debugger to track down the errors is invaluable if I can recreate the exact users steps within the debugger after the fact. However, at no point is ExceptionLogger being called, either running standalone or inside the debugger, and there is no visual indication that any error occurred. Because the exceptions are being suppressed, the users sometimes don't realize until much too late that everything they've done is completely screwed up and the data is even more corrupt.
The application platform is being built and run on x86 (apparently exceptions can be lost if run on x64), and the application has been tested on both 64-bit and 32-bit platforms with no change in behavior.
So you only see "but was not handled" when the app runs in the debugger. When it runs outside the debugger exceptions are suppressed. If I've got this correct then I still think the app handles the exceptions, because the debugger changes app behaviour sometimes.
I confirmed that InvalidCastException is one of a group of exceptions that .NET 4+ handles differently if the exception context is unmanaged code. An app can override this special handling (see All about Corrupted State Exceptions in .NET 4), but the debugger may ignore the override. There are lots of web resources on this, see also one in MSDN Magazine.
EDIT: If your app users have .NET 3.5 or below installed then the app need not apply the override described in the resources above.
Related
My winform application incorporates a 3rd-party dll (under the .NET 4.5) made by a device manufacturer in which I can use the exposed functions of its class to communicate with the device. But due to their crappy design once any function might fail no error detail can be retrieved from the class itself, but the class somehow put some information into the console window (appeared in the Output tab under Debug filter) in case of anything wrong.
Now the problem is, the application can only be executed on the computer that is authorized to communicate otherwise the class won't initiate. So when I test my application on the trusted computer, I can only know that some functions return false but no debug info available. I've tried to add TraceListener to Trace.Listeners but nothing shows from this answer, I also tried Debug.Listeners with no result even I manually flushes after each while.
System.Diagnostics.Trace.Listeners.Add(new System.Diagnostics.TextWriterTraceListener("debug.txt"));
System.Diagnostics.Trace.AutoFlush = true;
The DebugView won't generate anything either, I don't know it's because I don't know how to properly use this tool or not. I just opened it, and nothing shows whatever I do to my application.
I'm highly suspicious that this DLL might just use some try...catch snippet to capture its own exceptions and output those info not by using Debug.Write(). What else I can do? I simply can't just install another Visual Studio on that trusted machine and debug my application there.
Try adding a First-Chance Exception Handler:
using System;
using System.Runtime.ExceptionServices;
class Example
{
static void Main()
{
AppDomain.CurrentDomain.FirstChanceException +=
(object source, FirstChanceExceptionEventArgs e) =>
{
Console.WriteLine("FirstChanceException event raised in {0}: {1}",
AppDomain.CurrentDomain.FriendlyName, e.Exception.Message);
};
How to: Receive First-Chance Exception Notifications
I have quite an unusual problem where if there is a missing DLL on the client machine, the application will freeze and display the standard "The application is not responding". However, as I know what the issue is, I'd like to find a way to catch this exception (Missing DLL) and display the message in a dialog displaying meaningful information to help identify which DLL is missing. This will allow the application to have a more graceful death.
Upon debugging on the client machine, I receive the error:
A first chance exception of type 'System.Windows.Markup.XamlParseException' occurred in PresentationFramework.dll
Additional information: Could not load file or assembly 'Some.DLL' or one of its dependencies. The system cannot find the file specified.
In release however, the application crashes and is not responding.
Looking at the documentation for this error, a XamlParseException usually occurs inside the InitializeComponent(); method:
For pages of an application, when the XamlParseException is thrown, it is usually in the context of the InitializeComponent call made by your page class, which is the entry point for the WPF application model's usage of the WPF XAML parser at the per-page level. Therefore another possible handling strategy is to place try/catch blocks in InitializeComponent. However, this technique does not integrate well with templates, visual design surfaces and other generated sources that hook up InitializeComponent.
So, I can do something like this:
public MyView()
{
try
{
InitializeComponent();
}
catch (XamlParseException ex)
{
//Do something useful with the error.
}
}
This is certainly possible, however it would require using this code in practically all controls, which is obviously ridiculous. Not to mention that it doesn't really solve the issue of a missing DLL.
So, my questions are:
Is it possible to trap a missing DLL and display a message containing the name of said DLL?
Is there a more elegant way of catching a XamlParseException?
Thanks.
Yes, it is certainly possible.
To do this, you will need to override what happens when the application first starts up.
Open your Application.xaml.vb, and add the following code:
protected override void OnStartup(StartupEventArgs e)
{
// add an event handler for the UnhandledException event
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(HandleException);
// start up the application
base.OnStartup(e);
}
// what to do when the exception is thrown
void HandleException(object sender, UnhandledExceptionEventArgs e)
{
// do something with the exception
MessageBox.Show(e.ExceptionObject.ToString());
}
The output from the e.ExceptionObject.ToString() contains the problem. In the case you describe, there will probably be nested exceptions, the inner one stating : System.IO.FileNotFoundException: Could not load file or assembly '{missing DLL name here}' or one of its dependencies. The system cannot find the file specified. at {Project}.{where the error was thrown}
I have had a few reports of a message box showing up on application launch with the following contents:
[Arg_NullReferenceException]
Arguments:
Debugging resource strings are unavailable. Often the key and arguments provide
sufficient information to diagnose the problem. See http://go.microsoft...
I understand the link provided gives me the exception detail, and I obviously have a null ref somewhere. I haven't been able to reproduce this, so I am trying to find where this message is being thrown and hopefully add some error handling.
Is this specific message box something baked into Silverlight, or is it following whatever exception handling is in place when such an exception occurs? In the app constructor, I have
this.UnhandledException += this.Application_UnhandledException;
which is:
private void Application_UnhandledException(object sender,
ApplicationUnhandledExceptionEventArgs e)
{
MessageBox.Show(e.ExceptionObject.Message + "\n" + e.ExceptionObject.StackTrace);
}
So it looks like this message box is not coming from the Application_UnhandledException or it would have a message, newline, then a stack trace. So now my two options for how this message box is being generated are: 1) Silverlight is doing it in the background, or 2) this is coming from an existing catch block, although I have found none that would display in this way.
I'm doing offline caching of XAPs in Isolated Storage using OfflineCatalog, which involves some asynchronous WebClient downloads and fall-backs to Isolated Storage when requests fail. It makes sense that a null ref might be happening somewhere in this process.
To summarize, I'm wanting to add some exception handling for this Null Reference, but cannot reproduce it locally, and cannot find where it may be coming from. If this is coming from an unhandled exception, why does it not display the message and stack trace as specified?
The error message occurs if the machine does not have Silverlight SDK installed normally.
To debug similar browser side exceptions, it is common practice to use Visual Studio. If you cannot use VS, simply use WinDbg to attach to the browser process.
I have a C# WPF app that display an error dialog with the error code 0xc0000005. I researched this error code and found that it is a access violation error and could be caused by several things including native code errors (p/invoke and 3rd party dlls). Restarting the app seems to clear the error but I want to be able to force the app to close when that error occurs. Since it is not a managed code exception it is not caught in the try catch blocks, is there any way to force the app to close when this error occurs?
You can catch native exceptions in different way. Either using Win32Exception or SEHException exception class or using catch without any exception type specified as
try
{}
catch
{}
Refer this for details: Can you catch a native exception in C# code?
Use Environment.Exit(0); to terminate your application.
I apologize in advance if this is really a Super User question... I just wasn't sure, but this seems more on the dev. side than on the tech support side. :)
This isn't necessarily a problem, but it does actually drive me totally bonkers on my system. It also only happens on my computer.
When I launch any application, even a blank WPF application, I see four exceptions:
A first chance exception of type 'System.IO.DirectoryNotFoundException' occurred in PresentationCore.dll
A first chance exception of type 'System.ArgumentException' occurred in mscorlib.dll
A first chance exception of type 'System.ArgumentException' occurred in mscorlib.dll
A first chance exception of type 'System.InvalidOperationException' occurred in PresentationCore.dll
To figure out where these are coming from, I then set VS2008 to break on any thrown CLR exceptions, and here is the information:
Exception #1:
Cannot find a part of the path 'D:\Dell\Reader2.0\SPLASH.SYS\fonts\AscenderUni.ttf'.
Exception #2:
Culture name 'ug' is not supported.
Parameter name: name
Exception #3:
Culture name 'ug' is not supported.
Parameter name: name
Exception #4:
There is no registered CultureInfo with the IetfLanguageTag 'ug'.
I've poked through Process Monitor and Process Explorer. Process Monitor shows that my application is doing a RegQueryValue, which I'm certainly not responsible for... but some DLL (presumably from Dell crapware) is getting loaded by my process and is reading this regkey. I then looked at Process Explorer, hoping to see which DLLs my application is loading, but can't find that info. I then tried PrcView and saw the modules my application was loading.
I was surprised to see how many other modules were getting loaded, but I didn't see anything Dell related. I'm also wondering how it is possible that a Norton Internet Security DLL got loaded into my process, but I assume that's intended and something special that Norton does to ensure that a process is safe to execute.
What else can I do to identify and remove where these exceptions are coming from?
UPDATE
Not sure if it's confusing what I'm getting at here. This exception is raised in a DLL that my application loads for some reason (I don't reference anything Dell-related from my project). I've now uninstalled that app, and I still get the stupid exceptions. It's all technically fine because the exception is handled somewhere, presumably within that DLL, but I'm just annoyed because four extra messages (actually 8, since I have to close two dialogs per exception) pop up when I run my application. Call me lazy, but I never asked this damn DLL to load in the first place. :)
Perhaps now it's time to use msconfig to start disabling some Dell services. I'll play with that later when I actually have free time.
No file corruption. As I've been trying to hunt this one down for a while, I figured out what happened. Somewhere along the way, a font was installed with Uighur culture, which is, apparently a Turkish/Chinese culture (as best as I can tell), and their CultureInfo tag? "ug". When the fonts were cached, the system was attempting to load the Uighur culture. Sadly, my installation of Windows seems to be conspicuously missing this culture in Windows. Knowing that I won't be using the culture on my machine anytime soon, I followed the directions on MSDN to create and install a new culture.
Though the error won't hurt anything major. It is just a first chance exception, after all, it was annoying the crap out of me. So here's what I did.
Create a new console app.
Add a reference to sysglobal.
Add the following code:
var culture = new CultureAndRegionInfoBuilder("ug", CultureAndRegionModifiers.None);
var ci = new CultureInfo("en-US");
var ri = new RegionInfo("US");
culture.LoadDataFromCultureInfo(ci);
culture.LoadDataFromRegionInfo(ri);
culture.Register();
Build.
From Windows Explorer (you need admin privileges to do this), run the compiled executable as administrator.
If all goes well, there should now be a file in C:\windows\Globalization called "ug.nlp".
You shouldn't receive that message again.
I had the same problem.
It disappear after I did:
Clear the WPF font cache and restarted Visual Studio.
Clear the cache: http://support.microsoft.com/kb/937135
Éric
It is very unlikely to be the shovel-ware on your machine. These DLLs need to inject themselves also into non-managed programs, they have to be written in a language that doesn't depend on the CLR, like C or C++. And accordingly cannot generate managed exceptions.
These exceptions look like machine configuration problems to me. Junk in your registry. The bad culture name (sounds like "us" got corrupted to "ug") generates three of them, the font is probably listed in the registry but missing from the disk.
Short from a OS reinstall, you could possibly diagnose this by using both ProcMon and the debugger. Use Debug + Exceptions, Thrown checkbox to force the debugger to stop on the first-chance exception. When it hits, switch to ProcMon, the registry key or file should be visible very near the end of the trace.
With leads from the above answers I was able to solve this issue by deleting the font "Microsoft Uighur Regular"
First chance exceptions are normal - these are displayed whenever an exception is thrown, whether it was handled or not. They exist so you can go into your code and find out why they are thrown.
However, if the exception has been handled, there is no problem and execution will resume.
If the exception was not handled, a second chance exception will be caught by the debugger and execution will halt.
This is normal and shouldn't be of concern. You can always hide them - see this question and answers for more details.
In regards to the actual exceptions - there is some code (third party or your own) that is trying to access a ttf in the mentioned directory, this cannot be found, hence the exception (which was handled, so no problem).
The other exceptions are due to create a non existing CultureInfo (ug) - perhaps this is supposed to be uk? Check configuration and code for this.
These values may be configured in the registry.