Exemplo n.º 1
0
        private static Script genVersion(ScriptContext context)
        {
            Script script = createEmptyScript(context, "xsharper //version");;

            script.Id = "version";
            script.Add(new Set("process", "${=System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName}"));
            script.Add(new Set("net", "${=string.Join(', ',(string[])XS.Utils.GetInstalledNETVersions())}"));
            script.Add(new Print {
                OutTo = "^bold", Value = HelpHelper.GetLogo(context)
            });
            script.Add(new Print());
            script.Add(new Print {
                Transform = TransformRules.Trim | TransformRules.Expand, NewLine = false, Value = @"
Environment: 
====================
Operating system          : ${=Environment.OSVersion.VersionString}
Available .NET Frameworks : ${net}
.NET Framework            : ${=Environment.Version}
Current directory         : ${=.CurrentDirectory}
Privileges                : ${=.IsAdministrator?'Administrator':'Not administrator (use //requireAdmin)'}
XSharper executable       : ${process}
Configuration file        : ${=AppDomain.CurrentDomain.SetupInformation.ConfigurationFile} ${=File.Exists(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile)?'':'(does not exist)'}

Environment variables: 
=======================
XSH_PATH            : ${%XSH_PATH%|''}
XSH_REF             : ${%XSH_REF%|''}
XSH_COLORS          : ${%XSH_COLORS%|''}"
            });
            script.Add(new Print());
            return(script);
        }
Exemplo n.º 2
0
        private static int updateStage(ScriptContext cout, string[] args)
        {
            string procName = Process.GetCurrentProcess().MainModule.FileName;

            try
            {
                if (args[0] == "overwrite")
                {
                    cout.WriteLine(OutputType.Info, "XSharper update started.");
                }

                cout.WriteLine(OutputType.Info, "Terminating parent process #" + args[1]);
                Process p = Process.GetProcessById(Utils.To <int>(args[1]));
                if (p != null)
                {
                    p.Kill();
                    p.Close();
                }

                Stopwatch sw = Stopwatch.StartNew();
                cout.Write(OutputType.Info, "Waiting for program to close...");
                for (int i = 0; i < 15; ++i)
                {
                    cout.Write(OutputType.Info, ".");
                    Thread.Sleep(1000);

                    try
                    {
                        FileInfo fi = new FileInfo(args[2]);
                        if (!fi.Exists)
                        {
                            break;
                        }
                        fi.Attributes = FileAttributes.Normal;
                        using (var q = new FileStream(fi.FullName, FileMode.Open, FileAccess.Write, FileShare.None))
                            break;
                    }
                    catch
                    {
                    }
                }
                cout.WriteLine(OutputType.Info);

                switch (args[0])
                {
                case "overwrite":
                    cout.WriteLine(OutputType.Info, "Copying " + procName + " to " + args[2] + "...");
                    File.Copy(procName, args[2], true);
                    cout.WriteLine(OutputType.Info, "Waiting for 2 seconds...");
                    Thread.Sleep(2000);
                    ProcessStartInfo pi = new ProcessStartInfo
                    {
                        WorkingDirectory = Environment.CurrentDirectory,
                        FileName         = args[2],
                        Arguments        = "//" + xs.updateStage.Replace("xs.", "") + " delete " + Process.GetCurrentProcess().Id + " " + Utils.QuoteArg(procName),
                        UseShellExecute  = false,
                        CreateNoWindow   = false
                    };
                    cout.WriteLine(OutputType.Info, "Executing final part...");
                    Process pr = Process.Start(pi);
                    if (pr != null)
                    {
                        pr.WaitForExit();
                    }
                    return(0);

                case "delete":
                    cout.WriteLine(OutputType.Info, "Deleting a temporary file " + args[2]);
                    File.Delete(args[2]);
                    Thread.Sleep(2000);
                    cout.WriteLine(OutputType.Info, string.Empty);
                    cout.WriteLine(OutputType.Info);
                    cout.WriteLine(OutputType.Bold, HelpHelper.GetLogo(cout));
                    cout.WriteLine(OutputType.Info, "Update successful. The program will terminate in 5 seconds.");
                    Thread.Sleep(5000);
                    return(0);

                default:
                    return(-1);
                }
            }
            catch (Exception e)
            {
                cout.WriteLine(OutputType.Error, e.Message);
                cout.WriteLine(OutputType.Error, "Software update failed. The program will terminate in 5 seconds.");
                Thread.Sleep(5000);
                return(-1);
            }
        }
Exemplo n.º 3
0
        private static int upgrade(ScriptContext cout)
        {
            string procName = Process.GetCurrentProcess().MainModule.FileName;

            string tmp = null;

            try
            {
                cout.WriteLine(OutputType.Bold, HelpHelper.GetLogo(cout));
                cout.WriteLine(OutputType.Info, "Currently executing " + procName);
                if (BitConverter.ToString(Assembly.GetExecutingAssembly().GetName().GetPublicKeyToken()).Length == 0)
                {
                    cout.Write(OutputType.Error, "This XSharper build is not digitally signed and cannot be upgraded automatically. Please upgrade manually...");
                    return(-1);
                }

                // Find out if upgrade is due
                var current = Assembly.GetExecutingAssembly().GetName().Version;
                cout.Write(OutputType.Info, "Checking the latest XSharper version...");

                using (var wc = new WebClientEx())
                {
                    wc.CachePolicy = new RequestCachePolicy(RequestCacheLevel.Revalidate);

                    var verBytes = wc.DownloadData("http://www.xsharper.com/xsharper-version.txt");
                    var latest   = new Version(Encoding.ASCII.GetString(verBytes));
                    cout.WriteLine(OutputType.Info, string.Empty);
                    cout.WriteLine(OutputType.Info, "The latest available version is " + latest);
                    if (latest <= current)
                    {
                        cout.WriteLine("Installed XSharper version is up to date.");
                        return(0);
                    }

                    cout.WriteLine(OutputType.Info, "Downloading the latest XSharper binary...");
                    byte[] exe = wc.DownloadData(Environment.Version.Major >= 4?
                                                 "http://www.xsharper.com/xsharper4.exe" :
                                                 "http://www.xsharper.com/xsharper.exe");
                    Assembly a = Assembly.Load(exe);


                    tmp = Utils.BackslashAdd(Path.GetTempPath()) + "xsharper" + latest + ".exe";
                    File.WriteAllBytes(tmp, exe);


                    // Verify signature
                    cout.WriteLine(OutputType.Info, "Verifying digital signature...");

                    if (BitConverter.ToString(a.GetName().GetPublicKeyToken()) != BitConverter.ToString(Assembly.GetExecutingAssembly().GetName().GetPublicKeyToken()))
                    {
                        cout.Write(OutputType.Error, "Failed. The downloaded XSharper binary is signed with a different key. Please upgrade manually.");
                        return(-1);
                    }
                    cout.WriteLine(OutputType.Info, "Done.");

                    byte wasVerified = 0;
                    if (!StrongNameSignatureVerificationEx(tmp, 1, ref wasVerified))
                    {
                        cout.Write(OutputType.Error, "Downloaded XSharper binary has invalid signature. Upgrade is aborted.");
                        return(-1);
                    }

                    cout.WriteLine(OutputType.Info, string.Empty);
                }

                // Run it
                cout.WriteLine(OutputType.Info, "Starting update...");
                var pi = new ProcessStartInfo
                {
                    WorkingDirectory = Environment.CurrentDirectory,
                    FileName         = tmp,
                    Arguments        = xs.updateStage.Replace("xs.", "//") + " overwrite " + Process.GetCurrentProcess().Id + " " + Utils.QuoteArg(procName),
                    UseShellExecute  = true,
                };
                Process pr = Process.Start(pi);
                if (pr != null)
                {
                    pr.WaitForExit();
                }


                // If the script is successful, this process will be killed and this line never executed
                throw new ScriptRuntimeException("Failed to start upgrade");
            }
            catch (Exception e)
            {
                cout.WriteLine(OutputType.Error, e.Message);
                cout.WriteLine(OutputType.Error, "Software update is cancelled.");
                return(-1);
            }
            finally
            {
                if (tmp != null && File.Exists(tmp))
                {
                    File.Delete(tmp);
                }
            }
        }
Exemplo n.º 4
0
        static int MainWithContext(ScriptContext context, string[] args)
        {
            CommandLineParameters xsParams = getXsParams();
            int exitCode = 0;

            ConsoleRedirector redir = null;

            AppDomainLoader.progress("MainWithContext: Entering --------------------");
            bool utf8 = false;

            foreach (string arg in args)
            {
                if (arg.Equals(xs.utf8.Replace("xs.", "//"), StringComparison.OrdinalIgnoreCase))
                {
                    utf8 = true;
                }
            }
            using (ConsoleWithColors cout = new ConsoleWithColors(Environment.GetEnvironmentVariable("XSH_COLORS"), utf8))
                using (CtrlCInterceptor ctrl = new CtrlCInterceptor())
                {
                    context.Output += cout.OnOutput;
                    ctrl.Output     = context.Error;
                    ctrl.Abort     += delegate { context.Abort(); };

                    Stopwatch w = Stopwatch.StartNew();
                    try
                    {
                        // Parse arguments
                        var usage = new UsageGenerator()
                        {
                            Options = UsageOptions.None
                        };
                        xsParams.Parse(context, args, false);
                        setOutputOptions(context, cout);

                        if (context.IsSet(xs.path))
                        {
                            context.ScriptPath = context.GetString(xs.path);
                        }

                        // Load references
                        List <IScriptAction> preScript = getCommandlineReferences(context);

                        // Print help
                        if (args.Length == 0 || context.IsSet(xs.help))
                        {
                            loadReferences(context, preScript);
                            exitCode = HelpHelper.Help(context, usage, xsParams);
                            goto end;
                        }

                        // Handle upgrade
                        if (context.GetBool(xs.upgrade, false))
                        {
                            return(upgrade(context));
                        }
                        if (context.IsSet(xs.updateStage))
                        {
                            return(updateStage(context, context.GetStringArray(xs.updateStage)));
                        }

                        AppDomainLoader.progress("MainWithContext: Processing options");
                        // Process the remaining options
                        context.Compiler.AddRequireAdmin(Utils.To <RequireAdminMode>(context.GetStr(xs.requireAdmin, RequireAdminMode.User.ToString())));

                        if (context.IsSet(xs.codeout))
                        {
                            context.CodeOutputDirectory = Path.GetFullPath(context.GetString(xs.codeout));
                        }
                        if (context.IsSet(xs.genconfig) || context.IsSet(xs.gensample))
                        {
                            genDemoConfig(cout, context);
                        }
                        if (context.IsSet(xs.forcenet20))
                        {
                            context.Compiler.DefaultNETVersion = new Version(2, 0);
                        }

                        AppDomainLoader.progress("MainWithContext: Processing options, continuing");

                        List <string> filteredArgs = new List <string>();
                        if (context.IsSet(xs.scriptargs))
                        {
                            filteredArgs.AddRange(context.GetStringArray(xs.scriptargs));
                        }


                        // Run utilities, like //download etc
                        Script script     = getInlineScript(context, filteredArgs);
                        string scriptName = context.GetString(xs.script, null);
                        if (script == null)
                        {
                            // Load the script
                            if (scriptName == "/?" || scriptName == "-?")
                            {
                                for (int i = 0; i < args.Length; ++i)
                                {
                                    if (args[i] == "/?" || args[i] == "-?")
                                    {
                                        if (i != args.Length - 1)
                                        {
                                            context[xs.help] = args[i + 1];
                                        }
                                        break;
                                    }
                                }
                                loadReferences(context, preScript);
                                return(HelpHelper.Help(context, usage, xsParams));
                            }
                            if (scriptName != null)
                            {
                                AppDomainLoader.progress("MainWithContext: Loading script " + scriptName);
                                script = loadScript(scriptName, context);
                                AppDomainLoader.progress("MainWithContext: Loading completed");
                            }
                        }

                        AppDomainLoader.progress("MainWithContext: About to initialize");
                        // Attach script
                        if (script != null)
                        {
                            // Insert pre-script before the script body
                            int n = 0;
                            foreach (var list in preScript)
                            {
                                script.Items.Insert(n++, list);
                            }

                            AppDomainLoader.BaseDirectory = script.DirectoryName;

                            RequireAdminMode mode = context.Compiler.RequireAdmin;
                            if ((!context.IsAdministrator || context.GetBool(xs.testElevation, false)) && !isCodeGeneration(context) && mode != RequireAdminMode.User)
                            {
                                return(restartAsAdmin(context, args, mode == RequireAdminMode.Hidden && !(context.GetBool(xs.testElevation, false))));
                            }

                            AppDomainLoader.progress("MainWithContext: Before script initialization");
                            if (isCodeGeneration(context))
                            {
                                if (!context.EnableCodePrecompilation && (context.IsSet(xs.genexe) ||
                                                                          context.IsSet(xs.genwinexe) ||
                                                                          context.IsSet(xs.genlibrary) ||
                                                                          context.IsSet(xs.gencs)))
                                {
                                    throw new ParsingException("One of the loaded scripts has precompilation disabled. Executable cannot be generated from this script.");
                                }
                                context.EnableCodePrecompilation = false;
                            }
                            ctrl.IgnoreCtrlC = script.IgnoreCtrlC;
                            ctrl.AbortDelay  = Utils.ToTimeSpan(script.AbortDelay) ?? ctrl.AbortDelay;
                            ctrl.ExitDelay   = Utils.ToTimeSpan(script.ExitDelay) ?? ctrl.ExitDelay;
                            context.Initialize(script);

                            AppDomainLoader.progress("MainWithContext: Script initialization completed");
                        }

                        // After precompilation we're ready to write .exe, if requested
                        if (isCodeGeneration(context))
                        {
                            doCodeGeneration(context, script);
                        }
                        else if (script != null)
                        {
                            // Run the script
                            AppDomainLoader.progress("MainWithContext: Before script execution");
                            redir = new ConsoleRedirector(context);
                            try
                            {
                                object r = context.ExecuteScript(script, filteredArgs.ToArray(), CallIsolation.High);
                                if (r != null)
                                {
                                    int.TryParse(r.ToString(), out exitCode);
                                }
                            }
                            finally
                            {
                                ctrl.KillAbortTimer();
                                redir.Dispose();
                                redir = null;
                            }

                            AppDomainLoader.progress("MainWithContext: Script execution completed");
                        }
                    }
                    catch (ThreadAbortException ae)
                    {
                        AppDomainLoader.progress("MainWithContext: ThreadAbortException is being aborted");
                        resetAbort(context);
                        context.WriteException(ae);
                        exitCode = -1;
                    }
                    catch (ScriptTerminateException te)
                    {
                        exitCode = te.ExitCode;
                        resetAbort(context);
                        if (te.InnerException != null)
                        {
                            context.WriteException(te.InnerException);
                            AppDomainLoader.progress("MainWithContext: " + te.InnerException);
                        }
                        AppDomainLoader.progress("MainWithContext: Terminating with exit code " + exitCode);
                    }
                    catch (Exception e)
                    {
                        exitCode = -1;
                        resetAbort(context);
                        context.WriteException(e);
                        AppDomainLoader.progress("MainWithContext: " + e);
                    }
                    finally
                    {
                        resetAbort(context);
                        AppDomainLoader.BaseDirectory = null;
                    }
end:
                    // Display how long did it take
                    w.Stop();
                    if (context.GetBool(xs.wait, false))
                    {
                        cout.WriteLine(OutputType.Info, string.Format("Completed in {0} with exit code={1}. Press Enter to close...", w.Elapsed, exitCode));
                        Console.ReadLine();
                    }
                }
            AppDomainLoader.progress("MainWithContext: Exiting with code " + exitCode);
            return(exitCode);
        }