views:

51

answers:

3

Hello,

for an application I need to check the availability of Crystal Reports runtime libraries. What I've tried is:

    void CheckCrystal()
    {
        try
        {
            CrystalDecisions.Windows.Forms.CrystalReportViewer test = new CrystalDecisions.Windows.Forms.CrystalReportViewer();
            test.Dispose();
        }
        catch (System.Exception)
        {
            PTrace.Error("Some dependences needed to run Crystal Reports are not available.");
            throw;
        }
    }

This is not working because the File.IOException about the missing Crystal dependency is thrown in the method that calls CheckCrystal before calling the method. Is like .Net knows that it will need the assembly before needing it. Is this true? How can I change this behaviour?

Thanks in advance.

+5  A: 

This is because code is JITted on a per-method basis, so when you first try to invoke CheckCrystal(), .NET first tries to compile it, subsequently loading all required and not-yet-loaded assemblies.

.NET allows you to intercept a moment when assembly resolution fails. To do so, subscribe to AppDomain.AssemblyResolve event.

Anton Gogolev
+3  A: 

You would probably want to handle the AppDomain.AssemblyResolve event. More information here.

A quick and dirty example:

 AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

 private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
 {
     if (args.Name == "CrystalReports")
     {
         PTrace.Error("Some dependences needed to run Crystal Reports are not available.");
     }

     // return located here assembly here or throw exception, etc
 }
nukefusion
+3  A: 

Is like .Net knows that it will need the assembly before needing it. Is this true?

To improve startup performance the CLR lazily loads assemblies.

Either manually load or handle AppDomain.AssemblyResolve event.

Richard