public bool Run(string[] args, XtallStrategy strategy = null) { _args = args; _options = new Options(args); _strategy = strategy ?? new XtallStrategy(); try { _strategy.LogStatus("starting with command line: {0}", string.Join(" ", args)); if (_options.Keyed.Keys.Contains("uninstall:")) { Uninstall(_options.Keyed["uninstall:"]); return false; } if (_options.Loose.Count == 0) throw new ArgumentException("Site URL was not specified on the command line"); _strategy.InternalContext.Url = _options.Loose[0]; var @unsafe = true; // TODO get the strategy to handle this new Uri(_strategy.Context.Url).Scheme != "https"; // TODO: block unsafe unless environment is set up for it if (_options.Keyed.ContainsKey("debug:")) { _strategy.LogStatus("debug requested from the command line; no cache management will be used"); _strategy.InternalContext.Manifest = ManifestManager.Load(File.ReadAllText(_options.Keyed["debug:"])); _strategy.OnVerified(); _strategy.OnStatus("Debugging", 1.0); _strategy.OnSuccess(); } else { _strategy.OnStatus("Connecting and verifying", 0); if (!@unsafe) { _strategy.LogAction("setting the certificate validator"); ServicePointManager.CheckCertificateRevocationList = true; ServicePointManager.ServerCertificateValidationCallback = CheckServerCertificate; } else { _strategy.LogStatus("skipping server authentication checks"); } _strategy.LogAction("getting the manifest"); string manifestXml; using (var ms = new MemoryStream()) { _strategy.GetResource(_strategy.Context.Url + "/info", ms, t => t.StartsWith("text/xml")); ms.Seek(0, SeekOrigin.Begin); using (var sr = new StreamReader(ms)) manifestXml = sr.ReadToEnd(); } _strategy.LogAction("loading the manifest (first 100 characters are '{0}')", manifestXml.Substring(0, 100)); _strategy.InternalContext.Manifest = ManifestManager.Load(manifestXml); _strategy.LogAction("creating a code cache manager"); using (var cacheManager = new CodeCacheManager(_strategy)) { _strategy.LogAction("ensuring the boot package"); var candidate = Assembly.GetEntryAssembly().Location; var bootPath = cacheManager.EnsureBoot(candidate); if (bootPath == null) { _strategy.LogStatus("current process is the appropriate boot process"); _strategy.OnVerified(); _strategy.OnStatus("Loading", 0); UpdateInstall(cacheManager, candidate, _options.Keyed.Keys.Contains("install")); cacheManager.EnsureManifest(); _strategy.OnStatus("Loaded", 1.0); _strategy.OnSuccess(); } else { _strategy.LogStatus("current process is not executing the required image"); _strategy.LogAction("switching to image '{0}'", bootPath); _strategy.OnStatus("Transferring", 0); using (var p = Process.Start(bootPath, string.Join(" ", _args.Select(x => '"' + x + '"')))) { } _strategy.OnTransfer(); } } } } catch (Exception ex) { _strategy.OnFailure(ex); } return _strategy.WaitToProceed(); }