public override void WriteLine(string value) => Bridge.WriteLine(value);
Beispiel #2
0
        public static IEnumerator Install(string root)
        {
            Environment.CurrentDirectory = root;

            yield return(StatusSilent("Starting MiniInstaller", false, "monomod", false));

            using (MiniInstallerBridge bridge = new MiniInstallerBridge {
                Encoding = Console.Error.Encoding,
                Root = root
            }) {
                bridge.LogEvent = new ManualResetEvent(false);
                WaitHandle[] waitHandle = new WaitHandle[] { bridge.LogEvent };

                Thread thread = new Thread(() => {
                    AppDomain nest = null;
                    try {
                        AppDomainSetup nestInfo = new AppDomainSetup();
                        // nestInfo.ApplicationBase = Path.GetDirectoryName(root);
                        nestInfo.ApplicationBase    = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
                        nestInfo.LoaderOptimization = LoaderOptimization.SingleDomain;

                        nest = AppDomain.CreateDomain(
                            AppDomain.CurrentDomain.FriendlyName + " - MiniInstaller",
                            AppDomain.CurrentDomain.Evidence,
                            nestInfo,
                            AppDomain.CurrentDomain.PermissionSet
                            );

                        ((MiniInstallerProxy)nest.CreateInstanceAndUnwrap(
                             typeof(MiniInstallerProxy).Assembly.FullName,
                             typeof(MiniInstallerProxy).FullName
                             )).Boot(bridge);

                        AppDomain.Unload(nest);

                        bridge.IsDone = true;
                        bridge.WriteLine("MiniInstaller finished");
                    } catch (Exception e) {
                        bridge.Exception = e;

                        string msg = "MiniInstaller died a brutal death";

                        if (nest != null)
                        {
                            try {
                                AppDomain.Unload(nest);
                            } catch {
                                msg = "MiniInstaller has become a zombie";
                            }
                        }

                        bridge.IsDone = true;
                        bridge.WriteLine(msg);
                        Console.Error.WriteLine(e);
                    }
                })
                {
                    Name = "MiniInstaller"
                };

                thread.Start();

                string lastSent = null;
                while (!bridge.IsDone && thread.IsAlive)
                {
                    WaitHandle.WaitAny(waitHandle, 1000);
                    bridge.LogEvent.Reset();
                    if (lastSent != bridge.LastLogLine)
                    {
                        lastSent = bridge.LastLogLine;
                        yield return(StatusSilent(lastSent, false, "monomod", false));
                    }
                }

                thread.Join();

                if (bridge.Exception != null)
                {
                    throw new Exception("MiniInstaller died a brutal death", bridge.Exception);
                }
            }
        }