elifiner
elifiner

Reputation: 7575

How to prevent crash when a referenced assembly isn't found?

I have a small command line program that uses the Team System API. When the correct Team System isn't installed on the machine, the program prints a traceback with System.IO.FileNotFoundException, but it also crashes and shows the standard error messasge:

XXX has encountered a problem and needs to close. We are sorry for the inconvenience.

I just want my program to print a "The program requires Team System 2008" message to the console and quit without crashing.

From what I understand this whole loading process is happening before the first line of my C# code is run. Is there any way to control this?

Upvotes: 2

Views: 460

Answers (3)

Marc Gravell
Marc Gravell

Reputation: 1062550

.NET code is JITted on a method-by-method basis. Does your "Main" method make reference to the external libraries? If so, consider:

[MethodImpl(MethodImplOptions.NoInlining)]
static int Main() { // add "args" etc if needed
    try {
        return Main2();
    } catch (Exception ex) {
        Console.Error.WriteLine(ex.Message);
        return 1;
    }
}
static int Main2() { // add "args" etc if needed
    // your real code
}

I can't guarantee it will work, but it is worth a try...

Upvotes: 3

to StackOverflow
to StackOverflow

Reputation: 124696

Yes. The assembly will be loaded the first time you use a type that itself references a type from the assembly to be loaded.

So the solution is to create a helper class that wraps all interaction with the API. Then wrap calls to this wrapper class in a try/catch.

Something like:

public class Program
{
    static void Main()
    {
        try
        {
            WrapperClass.CallApi(...);
        }
        catch(FileNotFoundException)
        {
            ... you can e.g. show a MessageBox and exit here ... 
        }
    }
}

internal class WrapperClass
{
    public void CallApi(...)
    {
        ... you can reference types from the Team System assembly in WrapperClass
    }
}

Upvotes: 0

Nescio
Nescio

Reputation: 28403

You can try to Override CLR Assembly Probing Logic

In the .Net framework, when resolving an assembly reference, the CLR first checks the GAC, then searches the application directory in specific locations. If the assembly is not in one of those locations, CLR will fire AssemblyResolve event. You can subscribe to AssemblyResolve event and return the assembly using Assembly.LoadFrom/LoadFile, etc.

However, in your case, you can just show your messagebox and then shutdown cleanly.

Upvotes: 1

Related Questions