static void Perform(bool install, string executable) { ArrayList order = new ArrayList(); Hashtable states = new Hashtable(); try { Assembly a; if (assembly != null) { a = Assembly.Load(assembly); } else { a = Assembly.LoadFrom(executable); } Type [] types = a.GetTypes(); // todo: pass arguments, they are kind of useless though. InstallContext ctx = new InstallContext(); foreach (Type t in types) { if (!t.IsSubclassOf(typeof(Installer))) { continue; } object [] attrs = t.GetCustomAttributes(typeof(RunInstallerAttribute), false); if (attrs == null || attrs.Length == 0) { continue; } RunInstallerAttribute ria = attrs [0] as RunInstallerAttribute; if (ria == null || !ria.RunInstaller) { continue; } try { Installer installer = (Installer)Activator.CreateInstance(t); Hashtable state = new Hashtable(); order.Add(installer); states [installer] = state; if (install) { Call(installer, "OnBeforeInstall", state); } else { Call(installer, "OnBeforeUninstall", state); } installer.Install(state); if (install) { Call(installer, "OnAfterInstall", state); } else { Call(installer, "OnAfterUninstall", state); } } catch (Exception e) { Error(String.Format("Can not create installer of type {0}", t)); // // According to the docs uninstall should not do rollback // if (install) { foreach (Installer installer in order) { Hashtable state = (Hashtable)states [installer]; Call(installer, "OnBeforeRollback", state); installer.Rollback(state); Call(installer, "OnAfterRollback", state); } } } } // // Got it, now commit them // if (install) { foreach (Installer inst in order) { Hashtable state = (Hashtable)states [inst]; Call(inst, "OnCommitting", state); inst.Commit(state); Call(inst, "OnCommitted", state); } } } catch { Error(String.Format("Unable to load assembly {0}", assembly)); } }