/// <summary>
 /// Runs diagnostics on the specified file.
 /// </summary>
 /// <returns>
 /// The result of the diagnostics.
 /// </returns>
 /// <param name="plugin">
 /// The plugin to test.
 /// </param>
 public static DiagResult RunDiagnostics(FileInfo plugin)
 {
     DiagResult result = null;
     try {
         TestMachine tm = new TestMachine(plugin);
         result = tm.Run();
     }
     catch (Exception ex) {
         String reason = "Could not perform diagnostic tests on the specified file: " + ex.Message;
         result = new DiagResult(false, false, false, reason, null, ProcessorArchitecture.None);
     }
     return result;
 }
        /// <summary>
        /// Run this instance. This performs all the tests. A plugin is
        /// considered valid if all of the following conditions are true:
        /// - File exists.
        /// - File is a Mono/.NET assembly.
        /// - File is not an assembly that has already been loaded.
        /// - Assembly contains a public type that implements IPlugin.
        /// </summary>
        internal DiagResult Run()
        {
            DiagResult result = null;
            Type typeInterface = null;
            String reason = String.Empty;
            Version v = null;
            Boolean valid = false;
            Boolean isAssm = false;
            ProcessorArchitecture pa = ProcessorArchitecture.None;

            // Does the assembly even exist?
            Boolean exists = ((this._assembly != null) && (this._assembly.Exists));
            try {
                AppDomain temp = AppDomain.CurrentDomain;
                temp.ReflectionOnlyAssemblyResolve += new ResolveEventHandler(this.MyReflectionOnlyResolveEventHandler);
                Assembly asm = Assembly.ReflectionOnlyLoadFrom(this._assembly.FullName);

                // If we got this far, the file exists and is a valid Mono/.NET assembly.
                isAssm = true;

                // Get version and proc arch. Then check to see if the assembly
                // contains a type that implements our plugin interface.
                v = asm.GetName().Version;
                pa = asm.GetName().ProcessorArchitecture;
                foreach (Type asmType in asm.GetTypes()) {
                    if ((asmType.IsPublic) && (!asmType.IsAbstract)) {
                        typeInterface = asmType.GetInterface("CyrusBuilt.MonoPluginFramework.IPlugin", true);
                        if (typeInterface != null) {
                            valid = true;
                            break;
                        }
                    }
                }

                if (!valid) {
                    reason = "The assembly does not have any public types that implement CyrusBuilt.MonoPluginFramework.IPlugin.";
                }
            }
            catch (FileNotFoundException) {
                exists = false;
                reason = "The file could not be found.";
            }
            catch (BadImageFormatException) {
                exists = true;
                reason = "The file is not an assembly.";
            }
            catch (FileLoadException) {
                exists = true;
                reason = "The assembly has already been loaded.";
            }

            result = new DiagResult(exists, valid, isAssm, reason, v, pa);
            return result;
        }