Pull to refresh

Comments 15

UFO landed and left these words here

Одна из перегрузок CSharpScript.Create принимает параметром тип глобального объекта.
Его методы будут доступны из скрипта глобально.(если он не статический то в Create и RunAsync можно сам объект передать)


Script<object> script = CSharpScript.Create(File.ReadAllText(Program.options.Script), options, typeof (ScriptHost), null);
script.RunAsync(scriptHost, null, new CancellationToken()).Wait();
//Уже в скрипте вызываем метод от глобального объекта
StartSession("some-args");

код декомпилированный(не помню где исходники проекта), но смысл должен быть понятен.


Собственно сам студийный C# Interactive работает по такому же принципу поидее, но там глобальный тип это Console.(можно WriteLine писать прям так)

Возможно, там просто в ScriptOptions указан. Если добавить в него System.Console, то можно будет просто написать WriteLine(...), точно так же, как при использовании "using static System.Console".

вы имели в виду WriteLine наверно :)


там несколько способов помоему.
Потому что я использовал явно вариант и с ScriptOptions и с globalsType аргументами.

Да, спасибо, исправил.


Про вариант с globalsType учту.

Спасибо, что напомнили, постараюсь добавить в статью

Я обычно "скриптингом" на C# занимаюсь через Powershell. Очень удобно, когда нужен простенький GUI, например:


helloworldGui.ps1
$Assem = (
    “System.Windows.Forms”,
    "System.Drawing",
    "System.Core",
    "System.Data",
    "System.Xml"
    )
$Source = @”
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Infor.LMS.Utils.TranslationSearch
{

    public class Form1: Form
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.label1 = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(10, 10);
            this.label1.Name = "label1";
            this.label1.Font = new System.Drawing.Font("Segoe UI", 20F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);           
            this.label1.Size = new System.Drawing.Size(148, 13);
            this.label1.Text = "Hello world!";

            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(300, 200);
            this.Controls.Add(this.label1);
            this.Margin = new System.Windows.Forms.Padding(2);
            this.Name = "Form1";
            this.Text = "Hello World!";

            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Label label1;

        //End of codegen

        public Form1()
        {
            InitializeComponent();
        }
    }

    public static class Program 
    {
        public static void Start()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        } 
    }
}
“@

Add-Type -ReferencedAssemblies $Assem -TypeDefinition $Source -Language CSharp 

iex "[Infor.LMS.Utils.TranslationSearch.Program]::Start()"

более развитый инструмент предоставляет пакет DynamicExpresso
> для сериализации и десериализации лямбда-выражений

Главное не принимать от клиентской стороны лямбда выражения, иначе это готовый remote code execution

Да, вот для этого и искал, ограничение для доступных namespace-ов и reference-ов, но увы, не нашел. Можно у автора sharplab.io подсмотреть

С Microsoft.CodeAnalysis.CSharp.Scripting только одна проблема, если на .Net5 попытаться запаблишить как self-contained с флагом PublishSingleFile=true, то оно не работает (по крайней мере сейчас).

Sign up to leave a comment.

Articles