 |
|
 |
I read through the posts that pertain to this topic. I understand what you are doing as far as catching exceptions from within the application Would you be able to help with this question
Hi
I launch a program using the code below in Windows CE 6.0
I would like to detect Missing method exceptions that may be thrown from the
exe if one of the dlls it is dependent on does not exist.
WCHAR pszFileNameA [MAX_PATH] = {'"', '\\','H','a','r','d','
','D','i','s','k','\\','A','2','M','C','_','C','E','.','e','x','e', '"','\0'};
SHELLEXECUTEINFO sei = {0};
sei.cbSize = sizeof(sei);
sei.nShow = SW_SHOWNORMAL;
sei.lpFile = L"\\Hard Disk\\A2MC_CE.exe";
//sei.lpFile = pszFileNameA;
WriteStringToActivityLog("\nLaunching A2MC_CE.exe");
if(ShellExecuteEx(&sei) != 0)
{
WriteStringToActivityLog("\nA2MC_CE.exe successful");
}
else
{
subc.Write("A2MC CE Failed E960");
WriteStringToActivityLog("\nA2MC CE Failed E960");
}
Here is the beginng to the exe where I have tried to catch them inside the
exe.
The missing method exception always gets thrown and caught by the OS in a
debug window. The operating system must be trying to load the missing dll
that the exe is dependent on before the code below runs. Does anyone now how
to catch these missing method exceptions? Is there a way? I want to be able
to detect when my exe is missing components and do something about it rather
than getting a debug message window.
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
try
{
Console.WriteLine("Run the app");
Application.Run(new A2MotionControllerGUI());
}
catch(MissingMethodException e)
{
// Show the user that the DoSomething method cannot be called.
Console.WriteLine("Unable to call the method: {0}",
e.Message);
MessageBox.Show("Unable to call the method: {0}", e.Message);
}
}
}
}
|
|
|
|
 |
|
 |
I read through the posts that pertain to this topic. I understand what you are doing as far as catching exceptions from within the application Would you be able to help with this question
Hi
I launch a program using the code below in Windows CE 6.0
I would like to detect Missing method exceptions that may be thrown from the
exe if one of the dlls it is dependent on does not exist.
WCHAR pszFileNameA [MAX_PATH] = {'"', '\\','H','a','r','d','
','D','i','s','k','\\','A','2','M','C','_','C','E','.','e','x','e', '"','\0'};
SHELLEXECUTEINFO sei = {0};
sei.cbSize = sizeof(sei);
sei.nShow = SW_SHOWNORMAL;
sei.lpFile = L"\\Hard Disk\\A2MC_CE.exe";
//sei.lpFile = pszFileNameA;
WriteStringToActivityLog("\nLaunching A2MC_CE.exe");
if(ShellExecuteEx(&sei) != 0)
{
WriteStringToActivityLog("\nA2MC_CE.exe successful");
}
else
{
subc.Write("A2MC CE Failed E960");
WriteStringToActivityLog("\nA2MC CE Failed E960");
}
Here is the beginng to the exe where I have tried to catch them inside the
exe.
The missing method exception always gets thrown and caught by the OS in a
debug window. The operating system must be trying to load the missing dll
that the exe is dependent on before the code below runs. Does anyone now how
to catch these missing method exceptions? Is there a way? I want to be able
to detect when my exe is missing components and do something about it rather
than getting a debug message window.
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
try
{
Console.WriteLine("Run the app");
Application.Run(new A2MotionControllerGUI());
}
catch(MissingMethodException e)
{
// Show the user that the DoSomething method cannot be called.
Console.WriteLine("Unable to call the method: {0}",
e.Message);
MessageBox.Show("Unable to call the method: {0}", e.Message);
}
}
}
}
|
|
|
|
 |
|
 |
The reason that you are unable to catch MissingMethodExceptions is because the exception is thrown during the JITting fase and not during normal code execution.
So the following won't be possible
public void Method1()
{
try
{
SomeMissingMethod();
} catch (MissingMethodException)
{
}
}
Since JITting works on a per method basis, I can imagine that the following could be possible though, but I personally would not recommended relying on this behavior even if it does seem te work. It possibly won't continue to work on future versions of the .NET framework and it probably won't work at all when using NGEN:
public void Method1()
{
try
{
Method2();
} catch (MissingMethodException)
{
}
}
public void Method2()
{
SomeMissingMethod();
}
|
|
|
|
 |
|
|
 |
|
 |
yes, if you want the entire application to die when it can't copy a file, but he wants it to keep going.
|
|
|
|
 |
|
|
 |
|
 |
Out of an abundance of caution, I would suggest you call this method as soon as you instantiate the class that it is part of. The reason for this is to ensure that it has memory allocated. I know that simple types and static methods should not allocate memory, but I never trust compiler designers to that extent. Sometimes they 'just borrow a little memory' temporarily and a routine you think is safe, in fact is not.
Another caution to programmers who may not get this thing, even if you are confident this is 'the list' of critical messages, you are not always better off working this way. Bad things happen, but often not in isolation. Your code may be messed up by some wild pointers in native code, or some other nasty unexpected condition. It is not always safe to assume that things are not out of hand, especially with exceptions like this. So in the event that a really bad problem was happening in code, you would have to design so that this exception handler could be turned off, or removed from code in order to track it down.
Michael Rempel
|
|
|
|
 |
|
 |
Thank you for explaining the "Do Not Catch Exceptions That You Cannot Handle" rule - perhaps MSDN or www.asp.net should put your code up as "article of the day"! It is however, not just a C# problem, but affects VB.NET (and proabably every dot net language.)
In many situations (such as a web application), there come a point going up the call stack, that the error detail must be replaced by a bland "there has been an error - please contact support.".
Manifestly, the routine that caught the error must log it in as much detail as neccessary (preferably to a custom event log) and then set an error return code. As this error return, ascends the call stack, various other pieces of information may need to be logged as warning messages to the event log.
|
|
|
|
 |
|
 |
After reading through the article and the various posts replying to it, I can see the usefulness of the IsCritical approach within any given class library, however, the comments on hiding the exceptions are quite valid. I ended up inadvertently hiding an exception within a library in a recent project and it took ages to track down the problem.
An alternative approach here would be to do something like this...
// Create a generic exception for your library including an IsCritical flag.
// All other exceptions within the library should inherit from this one.
class MyLibraryException : System.Exception
{
// Sample constructor to determine if a given inner exception is rated as a critical exception
// within the context of the library. The criticality of a given exception from the perspective
// of the library may be different from the application that is using it.
public MyLibraryException(Exception innerException)
{
if (IsCritical(innerException))
{
isCritical = true;
}
else
{
isCritical = false;
}
}
private bool isCritical;
public bool IsCritical
{
get { return isCritical; }
set { isCritical = value; }
}
}
This kind of root exception then provides the recommendation of criticality, according to the library, to the application developer but it doesn't constrain the developer or hide any information from them.
This solution relies on effectively catching everything and rethrowing at least a MyLibraryException. This can then be interrogated for criticality and the nature of the innerException. The app developer can then do whatever they want with the caught exception, including throwing the innerException.
Keith Jackson
Developer
S-Cool Ltd.
|
|
|
|
 |
|
 |
I agree with your point of view. There are situations when it is not doable to catch all exceptions explicitly, and where the "any unknow exception is fatal" approach is not feasible, so it should be possible to deviate from the rule.
However, I do not quite agree with the list of exceptions that you check for criticalness.
BadImageFormatException: This exception is thrown when unmanaged code is passed to Load for loading. It can be used to check if a file is an assembly, there is a Microsoft How to example for that somewhere.
AppDomainUnloadedException: This one happens when you create a new application domain, unload it again and try to access it afterwards. This shows a problem with the application logic.
CannotUnloadAppDomainException: It just says that you cannot unload the application domain for various reasons.
These three are not critical in the sense that the rest of the application could not proceed. Of course, they can show problems with your 'unattended job loading and execution code', but still we can try to proceed with the next job, especially if we think of them as being caused by such a job.
InvalidProgramException: Even this one is not critical in all situations. It depends: If it is happening in your code, it is very critical. If it is happening in the job to be carried out, possibly after loading a plug-in that was built with an unknown tool, just state failure of this job and continue.
ThreadAbortException: The documentation says "ThreadAbortException is a special exception that can be caught, but it will automatically be raised again at the end of the catch block". But it certainly does not hurt to have it here.
StackOverflowException: This one is not in your list, and for 2.0 it is not necessary: "Starting with the .NET Framework version 2.0, a StackOverflowException object cannot be caught by a try-catch block and the corresponding process is terminated by default. " You might want to add it for version 1.1 code, though.
So the only two really critical ones are ExecutionEngineException and OutOfMemoryException.
The latter one can be avoided with the new MemoryFailPoint class.
|
|
|
|
 |
|
 |
I'm suprised that you didn't list ThreadAbortException as critical. If you catch that exception in a backgrond thread, then your application will not close. It will look closed, because the main form will disappear, but the app will still exist in the task list.
|
|
|
|
 |
|
 |
You're right. I should have added ThreadAbortException. I will update this article with this exception as soon as possible. Thanks for your feedback.
|
|
|
|
 |
|
 |
When writing unattended apps, I have had a problem with exception dialogs appearing on unhandled or unanticipated exceptions. When there is no user present, this may halt a system and prevent a possible recovery. I have tried many different APIS to catch all exceptions and simply log them or e-mail them and then terminate and restart the system. Somehow, there is always an exception that manages to "squeak by" and display a dialog box. I finally had to install my own CLR exception handler at the OS level because I could not always stop exception dialogs from coming up.
Granted, this does not solve extremely unrecoverable errors like disk full, but it at least allows an unattended system to have the change of staying up and recovering vs. sitting there waiting for someone to press OK to continue.
Although most people would say don't write code that causes exceptions, the fact is that you cannot account for all exceptions, especially if you are using 3rd party assemblies.
|
|
|
|
 |
|
 |
Hi,
Can you elaborate or post some code if possible on "Installing own CLR exception handler at the OS level". Seems it would be very helpful in one of our applications.
Thanks
Sujith Jagini
|
|
|
|
 |
|
 |
well i'm not sure what varnk meant, but here are some suggestions.
-- There are some events you could add a handler to, such as System.Windows.Forms.Application.ThreadException and System.AppDomain.CurrentDomain.UnhandledException.
-- In your main loop:
static void Main() {
try {
Application.Run(new MainForm());
} catch ...
}
|
|
|
|
 |
|
 |
First, I've noticed that the MFC designers don't follow the "don't eat exceptions you don't understand" rule. Their windows message handler catches CException, calls ReportError on it, and then deletes it. It seems that even the MFC team feels that the rule is not doable.
I've also found several situations in which displaying a message box is not an acceptable solution. If the code for drawing on a window throws an exception, for instance, a message box would allow the window to be drawn again before the user can press OK. However, one can still draw the text of the exception, and in C#, one could presumeably draw the stack trace as well. Another place is in ON_UPDATE_COMMAND_UI handlers. I haven't found much solution for that except to eat the exceptions.
The simple solution of loging info about exceptions that occur in a batch process seems at least as reasonable as MFC aproach of displaying a message box for anything that goes wrong. In fact, I think it's more so, since loging info about an exception won't cause the same exception to occur again.
Nathan Holt
|
|
|
|
 |
|
 |
It's nice to know that Microsoft doesn't follow their own rules. I've seen that before. Try running Microsoft FxCop against Application Blocks written by Microsoft and see if they pass.
I don't really know MFC. Does it have any code that does show the 'good'-way of doing things? Perhaps we can convert that to C#...
|
|
|
|
 |
|
 |
Michael Vanhoutte wrote:
I don't really know MFC. Does it have any code that does show the 'good'-way of doing things? Perhaps we can convert that to C#...
I don't know myself. While I've used MFC for years, I haven't studied the examples much. I usually look up classes and methods in the MSDN library.
Nathan Holt
|
|
|
|
 |
|
 |
My understanding is that they are trying to clean up the old C++ MFC behavior as they continue to replace it with Windows.Forms. They recognize that the specific problem you mention in the message handler is considered a bug and they're planning to fix it. From the June 2004 MSDN article "Unexpected Errors in Managed Applications":
http://msdn.microsoft.com/msdnmag/issues/04/06/NET/default.aspx
In certain cases, exceptions
that are unhandled are swallowed whole by the CLR
(although this behavior is changing in the .NET
Framework 2.0). Here is a summary of the unhandled
exception handler default behaviors that are
executing in this application.
- Unhandled exceptions that occur on the
application's main thread cause the application
to terminate.
- Unhandled exceptions that occur in threads
other than the application's main thread are
swallowed by the CLR. This includes manual
threads, thread pool threads, and the CLR's
finalizer thread. If your application is a
console application, the CLR outputs exception
text to the console (though your application
keeps running). If your application is not a
console application, there is no outward
indication when an exception occurs and your
application keeps running.
- Unhandled exceptions that occur on a thread
that is pumping window messages via the Windows
Forms classes are subject to the Windows Forms
unhandled exception handler. A debug dialog box
is produced by default, but this behavior can be
overridden (more on this in a moment).
Byron Jenings
|
|
|
|
 |
|
 |
It seems to me that a new system could create a different kind of critical error, which your function wouldn't have caught.
Perhaps a part of the problem is that the exception hierachy doesn't provide a way to distinguish minor exceptions from critical ones. I seem to recall that the standard C++ library exception system does have a badexception class or something like it that could be checked for. On the other hand, what a library designer thinks is a bad exception may not be what you think is a bad exception. I've had to deal with annoying exceptions thrown if I move to the beginning of an empty recordset.
Nathan Holt
|
|
|
|
 |
|
 |
A badexception-class would solve some of my problems but I agree that there could be some discussion between developers as to what a critical exception is. To me a critical exception is one that I can't possibly recover from gracefully. For example if my dll is corrupt. I personally would think that 'out of memory' is also a critical exception, but some application might decide to clear their cache when this exception occurs. That is an 'advantage' of the IsCritical-method: you can decide for yourself...
Still I agree, it's far from ideal.
|
|
|
|
 |
|
 |
We have the same problem with VB6. And it's worst because it throws error numbers rather than exception classes. I came with the solution to build an error handler library. When an error occurs, I call a static method named "TrapErr". Once an error is trapped, I can do some operations then decide to rethrow the error to the calling procedure or to add an entry in the log file or to display a message box with the possibility to see the details of the error. I also came with the conclusion that each errors that occurs in a component should always be treated internally and that component should always throw its own errors to the clients, with desired detailed informations on the error passed back. This worked very well for me.
|
|
|
|
 |
|
 |
I'm assuming that this also means that you might swallow an 'out of memory'-exception in your code?
|
|
|
|
 |
|
 |
Yes and no. If the form fails to display, it displays a message box instead. In the case of a stack overflow, the library could never be called, naturally. If there is no enough resources, the library could fail to do its job. I could prevent this by allocating the resources at the beginning of the program, but it never happens to be a common error. In either case the program will fail though.
|
|
|
|
 |
|
 |
Personally, I disagree with your statement that it is not doable to catch all of the exceptions explicitly. But, for the moment let’s say you are correct.
The one problem that I see with your way of catching and checking errors could still mask a problem. If there is a problem in the code that you are calling, whether it is a Microsoft method, a third party method, or one of your own methods and if the called method does not throw an expected exception then the code checking for the exceptions will still mask the error.
If you must generically catch exceptions, then you should look for the exceptions that you expect and wish to ignore (the non-critical ones). Any other exception that is given to you then must be a critical one regardless if it was in the documentation or not.
Just my opinion.
Jim
|
|
|
|
 |