Example #1
0
        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 ([email protected])
                    {
                        _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();
        }
Example #2
0
        // USAGE: preparealloyassets -source: file_source_folder -boot: boot_file_path [-passenger: passenger_file_path] [-pfx: pfx_file_path] [-ignore: ignore_regex] [-gzip] [-icon: icon_file_path] [-product: name] [-menupath: path] output_folder
        static void Main(string[] args)
        {
            try
            {
                Log("Preparing manifest with args '{0}'", string.Join(" ", args));

                var options = new Options(args);

                if (options.Loose.Count != 1)
                    throw new ArgumentException("Must specify exactly one output folder.");
                var outputPath = options.Loose[0];
                if (!options.Keyed.ContainsKey("source:"))
                    throw new ArgumentException("Must specify the file source folder (-source: file_source_folder).");
                if (!options.Keyed.ContainsKey("boot:"))
                    throw new ArgumentException("Must specify the boot file (-boot: boot_file_path).");
                var gzip = options.Keyed.ContainsKey("gzip");

                // prepare manifest using the source folder
                var sourceFolder = options.Keyed["source:"];
                Log("Preparing manifest using source folder '{0}'", sourceFolder);
                var prepared = ManifestManager.Prepare(sourceFolder, options.Keyed["boot:"], options.Keyed["product:"], options.Keyed["menupath:"], ignore: options.Keyed["ignore:"]);

                // write manifest output
                Directory.CreateDirectory(outputPath);
                var manifestPath = Path.Combine(outputPath, "manifest.xml");
                Log("Writing output '{0}'", manifestPath);
                var writer = XmlWriter.Create(manifestPath);
                writer.WriteStartDocument();
                ManifestManager.Write(writer, prepared);
                writer.WriteEndDocument();
                writer.Close();

                // move and prepare all files...
                var rawFolder = Path.Combine(outputPath, "raw");
                CleanFolder("uncompressed", rawFolder);

                var gzipFolder = Path.Combine(outputPath, "gzip");
                CleanFolder("gzip", gzipFolder);

                foreach (var file in prepared.Files)
                {
                    var sourcePath = Path.Combine(sourceFolder, file.Filename);
                    var rawPath = Path.Combine(rawFolder, file.Filename);
                    var gzipPath = Path.Combine(gzipFolder, file.Filename + ".gzip");

                    using (var sourcefile = File.OpenRead(sourcePath))
                    {
                        Log("Copying '{0}' to '{1}'", sourcePath, rawPath);
                        Directory.CreateDirectory(Path.GetDirectoryName(rawPath));
                        using (var rawfile = File.Open(rawPath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
                            sourcefile.CopyTo(rawfile);
                        sourcefile.Position = 0;

                        if (gzip)
                        {
                            Log("GZipping '{0}' to '{1}'", sourcePath, gzipPath);
                            Directory.CreateDirectory(Path.GetDirectoryName(gzipPath));
                            using (var gzipped = File.Open(gzipPath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
                            using (var compressor = new GZipStream(gzipped, CompressionMode.Compress, CompressionLevel.BestCompression))
                                sourcefile.CopyTo(compressor);
                        }
                    }
                }

                // prepare the shuttle
                using (var shuttleStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Xtall.XtallShuttle.exe"))
                {
                    var setup = Path.Combine(outputPath, "setup.exe");
                    using (var setupStream = File.Create(setup))
                    {
                        shuttleStream.CopyTo(setupStream);
                    }

                    string passengerFile;
                    if (options.Keyed.ContainsKey("passenger:"))
                        passengerFile = options.Keyed["passenger:"];
                    else
                        passengerFile = options.Keyed["boot:"];

                    var passenger = File.ReadAllBytes(Path.Combine(sourceFolder, passengerFile));
                    var pin = GCHandle.Alloc(passenger, GCHandleType.Pinned);

                    var handle = BeginUpdateResource(setup, false);
                    // TODO test and feedback

                    UpdateResource(handle, "EXE", "IDR_PASSENGER", 0, pin.AddrOfPinnedObject(), (uint) passenger.Length);

                    EndUpdateResource(handle, false);

                    using (var s = new FileStream(setup, FileMode.Append, FileAccess.Write))
                    using (var bw = new BinaryWriter(s))
                    {
                        const int luggageSpace = 1024;
                        bw.Write(new byte[luggageSpace]);
                        bw.Write((int)0x42000042); // parameter space signature
                        bw.Write((int) 0);
                        bw.Write((int) luggageSpace + Marshal.SizeOf(luggageSpace)*3);
                    }
                }
            }
            catch (Exception x)
            {
                Console.Error.WriteLine("error: {0}\r\n{1}", x.Message, x);
                Environment.ExitCode = 1;
            }
        }