5

我已经广泛使用 Python 来完成各种临时数据处理和辅助任务。由于我正在学习 C#,我认为看看我是否可以用 C# 重写其中一些脚本会很有趣。

是否有一个可执行文件可以使用 .cs 文件并运行它 ala python?

4

3 回答 3

4

你可以做这样的事情(使用与此类似的代码创建一个控制台应用程序)

...
using System.Reflection;
using System.CodeDom.Compiler;
...

namespace YourNameSpace
{
  public interface IRunner
  {
    void Run();
  }

  public class Program
  {
    static Main(string[] args)
    {
      if(args.Length == 1)
      {
        Assembly compiledScript = CompileCode(args[0]);
        if(compiledScript != null)
          RunScript(compiledScript);
      }
    }

    private Assembly CompileCode(string code)
    {
      Microsoft.CSharp.CSharpCodeProvider csProvider = new 
Microsoft.CSharp.CSharpCodeProvider();

      CompilerParameters options = new CompilerParameters();
      options.GenerateExecutable = false;
      options.GenerateInMemory = true;

      // Add the namespaces needed for your code
      options.ReferencedAssemblies.Add("System");
      options.ReferencedAssemblies.Add("System.IO");
      options.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);

      // Compile the code
      CompilerResults result;
      result = csProvider.CompileAssemblyFromSource(options, code);

      if (result.Errors.HasErrors)
      {
        // TODO: Output the errors
        return null;
      }

      if (result.Errors.HasWarnings)
      {
        // TODO: output warnings
      }

      return result.CompiledAssembly;
    }

    private void RunScript(Assembly script)
    {
      foreach (Type type in script.GetExportedTypes())
      {
        foreach (Type iface in type.GetInterfaces())
        {
          if (iface == typeof(YourNameSpace.Runner))
          {
            ConstructorInfo constructor = type.GetConstructor(System.Type.EmptyTypes);
              if (constructor != null && constructor.IsPublic)
              {
                YourNameSpace.IRunner scriptObject = constructor.Invoke(null) as 
YourNameSpace.IRunner;

                if (scriptObject != null)
                {
                  scriptObject.Run();
                }
                else
                {
                  // TODO: Unable to create the object
                }
              }
              else
              {
                // TODO: Not implementing IRunner
              }
            }
          }
        }
      }
  }
}

创建此控制台应用程序后,您可以在命令提示符下像这样启动:

YourPath:\> YourAppName.exe "public class Test : IRunnder { public void Run() { 
Console.WriteLine("woot"); } }"

您可以轻松地将 Main 方法更改为接受文件而不是内联代码,因此您的控制台应用程序将具有与 python 或 ruby​​ 解释器类似的行为。只需将文件名传递给您的应用程序,然后在主函数中使用 StreamReader 读取它,然后将内容传递给 CompileCode 方法。像这样的东西:

static void Main(string[] args)
{
  if(args.Length == 1 && File.Exists(args[0]))
  {
    var assambly = CompileCode(File.ReadAllText(args[0]));
    ...
  }  
}

在命令行上:

YourPath:\> YourApp.exe c:\script.cs

你必须实现 IRunner 接口,你也可以简单地调用一个硬编码的 Start 方法而不继承接口,这只是为了展示动态编译和执行类的概念。

希望它有所帮助。

于 2011-06-02T10:53:15.477 回答
1

CS-Script:C# 脚本引擎

http://www.csscript.net/

于 2011-05-18T07:45:38.543 回答
0

将 C# 作为脚本运行的最新和最佳方法是利用 Roslyn。这是用 C# 编写的 C# 编译器。

Glenn Block、Justin Rusbatch 和 Filip Wojcieszyn 已将 Roslyn 打包到一个名为 的程序中,该程序scriptcs完全符合您的要求。

您可以在此处找到该项目。http://scriptcs.net/

server.csx您可以运行通过调用调用的 C# 脚本文件

scriptcs server.csx
于 2016-07-28T06:06:34.673 回答