c# - 新建C# Assembly对预定义函数的访问

标签 c# scripting assemblies codedom

好吧,我首先承认我不知道所有这一切的正确术语,所以如果这个问题已经解决,我深表歉意,我只是没有使用适当的词。

我正在尝试用 C# 编写一个程序,允许程序编译的 C# 代码充当脚本语言。

这是我加载和编译代码的程序的示例代码:

using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Reflection;

namespace RuntimeCompilation
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Program b = new Program();
            CompilerResults results = b.BuildAssembly("Class1.cs"); // compiles the class

            if (results.Errors.Count > 0)
            {
                System.Console.Out.WriteLine("Errors Follow:");
                String ErrorText = "";
                foreach (CompilerError CompErr in results.Errors)
                {
                    ErrorText = ErrorText +
                        "Line number " + CompErr.Line +
                        ", Error Number: " + CompErr.ErrorNumber +
                        ", '" + CompErr.ErrorText + ";" +
                        Environment.NewLine + Environment.NewLine;
                }
                System.Console.Out.WriteLine(ErrorText);
            }
            else
            {
                Assembly assembly = results.CompiledAssembly;
                foreach (Type type in assembly.GetTypes())
                {
                    System.Console.WriteLine("Type found: " + type.FullName);
                    System.Console.WriteLine("Creating Instance:");
                    System.Console.WriteLine("=======================");
                    assembly.CreateInstance(type.FullName);
                    System.Console.Out.WriteLine("=======================");
                    System.Console.Out.WriteLine("Done");
                }
            }
            System.Console.Out.WriteLine("DONE.");
        }

        // Compile a file of source and return the CompilerResults object.
        private CompilerResults BuildAssembly(string filename)
        {
            TextReader tr = new StreamReader(filename);
            string code = tr.ReadToEnd();
            CSharpCodeProvider provider = new CSharpCodeProvider();
            CompilerParameters compilerparams = new CompilerParameters();
            compilerparams.GenerateExecutable = false;
            compilerparams.GenerateInMemory = true;
            return provider.CompileAssemblyFromSource(compilerparams, code);
        }

        public bool iCanHasAccess()
        {
            return true;
        }
    }
}

这是它构建的类:

using System;
using RuntimeCompilation;

namespace RuntimeCompilation
{
    public class Class1
    {
        public Class1()
        {
            System.Console.WriteLine("This was instancialized");
            if (Program.iCanHasAccess())
                System.Console.WriteLine("I have access");
        }
    }
}

程序输出的错误是名称 Program 在当前上下文中不存在。如何确保“脚本”程序可以访问编译程序的函数和成员?

我正在尝试提供一种运行时开销最小的简单方法,让用户无需重新构建即可修改程序中组件的行为。如果这无法通过 C# 程序集实现,我可能会使用 LUA,但我想避免使用它。因为我希望这个产品在 XBox360 上工作,所以需要在通过 XNA 部署之前将整个项目和脚本编译在一起。

最佳答案

您需要引用当前程序集,例如:

compilerparams.ReferencedAssemblies.Add("my.dll"); // or .exe

但是 - 以下仍然会失败:

        if (Program.iCanHasAccess())
            System.Console.WriteLine("I have access");

因为iCanHasAccess() 是一个实例 方法,而不是一个static 方法。

关于c# - 新建C# Assembly对预定义函数的访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4932800/

相关文章:

java - 与多个监听器的简单进程间通信

linux - 非常慢的脚本

visual-studio - 如何将程序集版本号 1 增加 1

c# - 从卫星组件中获取所有支持的文化

C# 相对于程序集 DLL 而不是 EXE 的路径

c# - 有没有办法在 .NET 4 中使用 C# 6 或更高版本?

c# - 0xFF 变成 0x3F

c# - 重绘时如何修复面板闪烁?

matlab - 在 Matlab 中保存当前运行的脚本

c++ - 一种简单编译的脚本语言