代码之家  ›  专栏  ›  技术社区  ›  NoizWaves

可以序列化C代码块吗?

  •  20
  • NoizWaves  · 技术社区  · 17 年前

    我在用C#with .NET 3.5. 是否可以序列化一段代码,将它传输到某个地方,反序列化它,然后执行它?

    Action<object> pauxPublish = delegate(object o)
    {
        if (!(o is string))
        {
            return;
        }
        Console.WriteLine(o.ToString());
    };
    Transmitter.Send(pauxPublish);
    

    使用某些远程程序执行以下操作:

    var action = Transmitter.Recieve();
    action("hello world");
    

    我的最终目标是能够在不同的进程中执行任意代码(事先不知道代码)。

    7 回复  |  直到 14 年前
        1
  •  19
  •   Brian Genisio    17 年前

    我们这样做是为了一个非常真实的性能案例。由于性能原因,在运行时执行此操作或使用DSL不是一个选项。

    在重新水合时,我们使用 类,并执行它。

    我们这样做是因为速度。我们有成千上万的小代码块。不幸的是,编译一段代码并运行它至少需要250毫秒,这对我们来说太慢了。我们采用了这种方法,而且效果非常好。在运行时,重建方法并运行它需要不可测量的时间。

    唯一需要注意的是。。。已签名程序集和未签名程序集不能混合序列化的方法数据。

        2
  •  7
  •   Peter Mortensen Pieter Jan Bonestroo    14 年前

    你可以尝试使用 IronPython trivial 在Python中执行要求的操作。Python代码可以调用您的C#方法。至于安全性,您可以在某种受限环境中执行代码(例如 RestrictedPython ).

        3
  •  4
  •   VVS    17 年前

    一般来说,这听起来是一个非常糟糕的主意,也是一个很大的安全漏洞。

        4
  •  3
  •   halfer Jatin Pandey    9 年前

    您也可以将其作为字符串发送,然后使用CodeDomProvider对其进行编译,结果相同。我有一段代码示例,如下所示:

    using System;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    using Microsoft.CSharp;
    
    namespace DynamicCodeApplication
    {
        class azCodeCompiler
        {
            private List<string> assemblies;
    
            public azCodeCompiler()
            {
                assemblies = new List<string>();
                scanAndCacheAssemblies();
            }
    
            public Assembly BuildAssembly(string code)
            {
    
                CodeDomProvider prov = CodeDomProvider.CreateProvider("CSharp");
                string[] references = new string[] { };   // Intentionally empty, using csc.rsp
                CompilerParameters cp = new CompilerParameters(references)
                                            {
                                                GenerateExecutable = false,
                                                GenerateInMemory = true
                                            };
                string path = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();
                cp.CompilerOptions = "@" + path + @"\csc.rsp";
                CompilerResults cr = prov.CompileAssemblyFromSource(cp, code);
    
                foreach (CompilerError err in cr.Errors)
                {
                    Console.WriteLine(err.ToString());
                }
                return cr.CompiledAssembly;
            }
    
            public object ExecuteCode(string code,
                                      string namespacename, string classname,
                                      string functionname, bool isstatic, params object[] args)
            {
                object returnval = null;
                Assembly asm = BuildAssembly(code);
                object instance = null;
                Type type = null;
                if (isstatic)
                {
                    type = asm.GetType(namespacename + "." + classname);
                }
                else
                {
                    instance = asm.CreateInstance(namespacename + "." + classname);
                    type = instance.GetType();
                }
                MethodInfo method = type.GetMethod(functionname);
                returnval = method.Invoke(instance, args);
                return returnval;
            }
    
            private void scanAndCacheAssemblies()
            {
    
                /*
                foreach (string str in Directory.GetFiles(@"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727"))
                {
                    if (str.Contains(".dll"))
                    {
                        foreach (string st in str.Split(new char[] { '\\' }))
                        {
                            if (st.Contains(".dll"))
                            {
                                assemblies.Add(st);
                            }
                        }
                    }
                }
                 * */
    
                assemblies.Add("Accessibility.dll");
                assemblies.Add("AspNetMMCExt.dll");
                assemblies.Add("cscompmgd.dll");
                assemblies.Add("CustomMarshalers.dll");
                assemblies.Add("IEExecRemote.dll");
                assemblies.Add("IEHost.dll");
                assemblies.Add("IIEHost.dll");
                assemblies.Add("Microsoft.Build.Conversion.dll");
                assemblies.Add("Microsoft.Build.Engine.dll");
                assemblies.Add("Microsoft.Build.Framework.dll");
                assemblies.Add("Microsoft.Build.Tasks.dll");
                assemblies.Add("Microsoft.Build.Utilities.dll");
                assemblies.Add("Microsoft.Build.VisualJSharp.dll");
                assemblies.Add("Microsoft.CompactFramework.Build.Tasks.dll");
                assemblies.Add("Microsoft.JScript.dll");
                assemblies.Add("Microsoft.VisualBasic.Compatibility.Data.dll");
                assemblies.Add("Microsoft.VisualBasic.Compatibility.dll");
                assemblies.Add("Microsoft.VisualBasic.dll");
                assemblies.Add("Microsoft.VisualBasic.Vsa.dll");
                assemblies.Add("Microsoft.Vsa.dll");
                assemblies.Add("Microsoft.Vsa.Vb.CodeDOMProcessor.dll");
                assemblies.Add("Microsoft_VsaVb.dll");
                assemblies.Add("mscorlib.dll");
                assemblies.Add("sysglobl.dll");
                assemblies.Add("System.configuration.dll");
                assemblies.Add("System.Configuration.Install.dll");
                assemblies.Add("System.Data.dll");
                assemblies.Add("System.Data.OracleClient.dll");
                assemblies.Add("System.Data.SqlXml.dll");
                assemblies.Add("System.Deployment.dll");
                assemblies.Add("System.Design.dll");
                assemblies.Add("System.DirectoryServices.dll");
                assemblies.Add("System.DirectoryServices.Protocols.dll");
                assemblies.Add("System.dll");
                assemblies.Add("System.Drawing.Design.dll");
                assemblies.Add("System.Drawing.dll");
                assemblies.Add("System.EnterpriseServices.dll");
                assemblies.Add("System.Management.dll");
                assemblies.Add("System.Messaging.dll");
                assemblies.Add("System.Runtime.Remoting.dll");
                assemblies.Add("System.Runtime.Serialization.Formatters.Soap.dll");
                assemblies.Add("System.Security.dll");
                assemblies.Add("System.ServiceProcess.dll");
                assemblies.Add("System.Transactions.dll");
                assemblies.Add("System.Web.dll");
                assemblies.Add("System.Web.Mobile.dll");
                assemblies.Add("System.Web.RegularExpressions.dll");
                assemblies.Add("System.Web.Services.dll");
                assemblies.Add("System.Windows.Forms.dll");
                assemblies.Add("System.XML.dll");
                assemblies.Add("vjscor.dll");
                assemblies.Add("vjsjbc.dll");
                assemblies.Add("vjslib.dll");
                assemblies.Add("vjslibcw.dll");
                assemblies.Add("vjssupuilib.dll");
                assemblies.Add("vjsvwaux.dll");
                assemblies.Add("vjswfc.dll");
                assemblies.Add("VJSWfcBrowserStubLib.dll");
                assemblies.Add("vjswfccw.dll");
                assemblies.Add("vjswfchtml.dll");
                assemblies.Add("Accessibility.dll");
                assemblies.Add("AspNetMMCExt.dll");
                assemblies.Add("cscompmgd.dll");
                assemblies.Add("CustomMarshalers.dll");
                assemblies.Add("IEExecRemote.dll");
                assemblies.Add("IEHost.dll");
                assemblies.Add("IIEHost.dll");
                assemblies.Add("Microsoft.Build.Conversion.dll");
                assemblies.Add("Microsoft.Build.Engine.dll");
                assemblies.Add("Microsoft.Build.Framework.dll");
                assemblies.Add("Microsoft.Build.Tasks.dll");
                assemblies.Add("Microsoft.Build.Utilities.dll");
                assemblies.Add("Microsoft.Build.VisualJSharp.dll");
                assemblies.Add("Microsoft.CompactFramework.Build.Tasks.dll");
                assemblies.Add("Microsoft.JScript.dll");
                assemblies.Add("Microsoft.VisualBasic.Compatibility.Data.dll");
                assemblies.Add("Microsoft.VisualBasic.Compatibility.dll");
                assemblies.Add("Microsoft.VisualBasic.dll");
                assemblies.Add("Microsoft.VisualBasic.Vsa.dll");
                assemblies.Add("Microsoft.Vsa.dll");
                assemblies.Add("Microsoft.Vsa.Vb.CodeDOMProcessor.dll");
                assemblies.Add("Microsoft_VsaVb.dll");
                assemblies.Add("mscorlib.dll");
                assemblies.Add("sysglobl.dll");
                assemblies.Add("System.configuration.dll");
                assemblies.Add("System.Configuration.Install.dll");
                assemblies.Add("System.Data.dll");
                assemblies.Add("System.Data.OracleClient.dll");
                assemblies.Add("System.Data.SqlXml.dll");
                assemblies.Add("System.Deployment.dll");
                assemblies.Add("System.Design.dll");
                assemblies.Add("System.DirectoryServices.dll");
                assemblies.Add("System.DirectoryServices.Protocols.dll");
                assemblies.Add("System.dll");
                assemblies.Add("System.Drawing.Design.dll");
                assemblies.Add("System.Drawing.dll");
                assemblies.Add("System.EnterpriseServices.dll");
                assemblies.Add("System.Management.dll");
                assemblies.Add("System.Messaging.dll");
                assemblies.Add("System.Runtime.Remoting.dll");
                assemblies.Add("System.Runtime.Serialization.Formatters.Soap.dll");
                assemblies.Add("System.Security.dll");
                assemblies.Add("System.ServiceProcess.dll");
                assemblies.Add("System.Transactions.dll");
                assemblies.Add("System.Web.dll");
                assemblies.Add("System.Web.Mobile.dll");
                assemblies.Add("System.Web.RegularExpressions.dll");
                assemblies.Add("System.Web.Services.dll");
                assemblies.Add("System.Windows.Forms.dll");
                assemblies.Add("System.XML.dll");
                assemblies.Add("vjscor.dll");
                assemblies.Add("vjsjbc.dll");
                assemblies.Add("vjslib.dll");
                assemblies.Add("vjslibcw.dll");
                assemblies.Add("vjssupuilib.dll");
                assemblies.Add("vjsvwaux.dll");
                assemblies.Add("vjswfc.dll");
                assemblies.Add("VJSWfcBrowserStubLib.dll");
                assemblies.Add("vjswfccw.dll");
                assemblies.Add("vjswfchtml.dll");
    
    
                return;
            }
        }
    }
    
        5
  •  1
  •   Daniel Earwicker    17 年前

    将它编译成一个单独的程序集,发送程序集,让其他进程加载它。

    更新:

    http://www.codeplex.com/metalinq/

        6
  •  1
  •   JacquesB    17 年前

    这是一个有趣的挑战,但您可能应该描述为什么要这样做,因为根据您的目标有很多不同的方法。正如Humbohl指出的,还有一些相当严重的安全问题。

    如果您想动态生成代码并将其传递,那么可以使用CodeDOM生成代码并对其进行编译。但是,您很可能不需要生成完全任意的代码。

        7
  •  0
  •   Peter Mortensen Pieter Jan Bonestroo    14 年前
    推荐文章