Link to home
Start Free TrialLog in
Avatar of goopyJava
goopyJava

asked on

How to Handle Third Party Exception in During Exit

All,

I am a contractor working building a large commercial piece of software. Because of limited time and resources I have to rely on third parties from time to time to get things built faster, better or just simply more cheaply than I can do myself. Because of this exact reason I am using a third party TWAIN interface, that was written in .NET.

In this particular piece of software it came with a "trial license" and everything seemed to be working fine. I purchased the software and again, things seemed to be working fine until I logged on to the machine as a non-administrator and my software crashed after the last line of MY code has run. Piecing things down a bit further (using reflector) I found out that the license provider for this component is relies on an internal static LicenseProvider variable which isn't finalized till after my application closes. Interestingly, this variable (on dispose, of course) tries to delete a file on the hard drive which it doesn't have access to and so it crashes (a license file that was stupidly created by the same provider earlier).

My question is - without throwing out a third party component that mostly works is their any way to prevent finalize routines from being called or to catch exceptions that happen while the GC is finalizing objects? I have search google but the most suggestions require access to the code which I don't have. Hopefully someone has an idea to try.

Personally, my best idea to date is loading the third party in its own app domain and unloading the domain once I am finished with it but I don't really know much of what that looks like in code. Any help is appreciated.

Thanks!
Avatar of tculler
tculler
Flag of United States of America image

Well, I'm not sure if this will solve your entire problem, but here's a rough idea of what the code would look like using AppDomain:


        private static System.AppDomain domain;
 
        internal static void SomeFunction()
        {
            // Create domain when necessary
            System.AppDomain domain = System.AppDomain.CreateDomain("<Insert Assembly's FriendlyName here>");
            domain.Load(new System.Reflection.AssemblyName("FullName property of Assembly"));
 
            //Unload the AppDomain whenever you wish by invoking the static Unload method of System.AppDomain
            System.AppDomain.Unload(domain);
        }

Open in new window

Avatar of goopyJava
goopyJava

ASKER

Do you believe that Finalize exceptions can be caught when AppDomain.Unload is called?
Like I said, probably won't solve your entire problem, but that's how you go about creating Application Domains. What is the exact type of exception thrown?
Right after I close the program I get a screen that pops up and says "<program name> has encountered an error and needs to close". Clicking to see the error report isn't very helpful.

Well, since I already closed the program this really just annoys me (as it will users). Tracking this down wasn't that hard - some debugging quickly showed it was after the main thread finished running. Presumably something with the GC. I just thought about things I had done recently and remembered the third party TWAIN app. Taking this out fixed the issue, but I need the TWAIN stuff in the software...

I would try the app domain stuff but reflection takes so long to program. Do you have any thoughts on how to load a dll dynamically but build like its static? Or possibly there is another way to do all this I haven't thought up.

Thanks again!
Yeah, that's quite a pickle... Unfortunately, I'm not very good at adapting to others' programs--I prefer to use my own. My last suggestion entails the most work out of them all--program our own version. I've found that Security issues are truly the biggest pain in the ass of them all, being extrememly difficult to work around, if there even is a work-around at all.

My last suggestion is pretty lame: get in contact with the creators of the program, and see what they think, or ask if they would give you access to the code. From there, you can hack things up a bit and make it a bit more friendly, maybe catch the exception, or prevent the code that's throwing it from running in the first place.

Sorry for the delay--in the process of moving households.

Hoped I helped at least a bit,
Nate
I appreciate the help. Actually your suggestion was right in line for what I was already trying. At the same time that I posted the question here I also sent a question to the developer of the software to see if they had a solution to the issue. I believe with proper coding they should be able to solve this one. I only hoped that there was another solution which didn't involved contacting the developer. If you do think of something, please feel free to post the suggestion as a comment. Otherwise I shall be closing this question soon.

Thanks again.
Well, I may have found a solution. Call the following method early on in your code (Main method, right before you call Application.Run is ideal)

System.Windows.Forms.Application.ThreadException += Application_ThreadException; // Or choose a different name, doesn't matter

Then, implement the following method (or use an anonymous method and place it above--again, doesn't matter)
ASKER CERTIFIED SOLUTION
Avatar of tculler
tculler
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Whoops, hit submit somehow. Here's the method you need to implement:

static void Application_ThreadException(System.Object sender, System.Threading.ThreadExceptionEventArgs excArgs)
{
     // Handle the thread exception here
}

However, you should note that this code will basically catch ALL EXCEPTIONS. Your try-catch'es and such will take precedence and prevent this method from executing, but if ANY exception occurs thorughout your application, this method will execute. If you have a finally block and no catch-blocks are executed, but an exception is thrown in a try-block, your finally block is executed FIRST, immediately followed by your ThreadException handling method.



Hope that helped, and hope you even see this, heh,

Nate
Thanks for your solution - looks like that worked. I had no idea that event event existed!