我如果希望在网络上移动的不是数据,而是代码,也就是把远端并不存在的方法传递给远 
端并执行,怎样才能实现呢? 

解决方案 »

  1.   

    简单方案:将DLL文件传过去,然后动态加载。
    复杂方案:将程序代码传过去,然后动态编译。
      

  2.   

    使用remoting + 反射
      

  3.   

    简单方案:将DLL文件传过去,然后动态加载。
    复杂方案:将程序代码传过去,然后动态编译。
    支持一楼
      

  4.   

    将DLL文件传过去,然后动态加载。
      

  5.   

    谢大家,思考并尝试中……
    回cnming(cnming) :
    我准备用.NET实现移动agent。
    远端可能是资源很有限的嵌入式系统,并且将独立运行许久而人们不能干预,于是希望可以在不对远端进行改动的情况下,让它执行别处传递来的代码
      

  6.   

    http://blog.csdn.net/dragonsuc/archive/2003/06.aspx
      

  7.   

    用反射,贴个我今天刚调通的代码,参考了其他前辈的,反射执行string的class代码,实现计算"1+2-3"这样字符串的结果和 判断1 + 2 == 2这样的逻辑表达式是否正确的功能。
    大家提提意见,另外反射调用的东东很难释放,曾看到过用Remoting+反射来执行完就释放的例子,大家可以找找看。
    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.CodeDom.Compiler;
    using Microsoft.CSharp;
    using System.Reflection;
    using System.Text;namespace WindowsApplication1
    {
    /// <summary>
    /// Form1 的摘要说明。
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
    private System.Windows.Forms.TextBox textBox1;
    private System.Windows.Forms.Label label1;
    private System.Windows.Forms.Button button1;
    private System.Windows.Forms.Button button2;
    private System.Windows.Forms.Label label2;
    /// <summary>
    /// 必需的设计器变量。
    /// </summary>
    private System.ComponentModel.Container components = null; public Form1()
    {
    //
    // Windows 窗体设计器支持所必需的
    //
    InitializeComponent(); //
    // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
    //
    } /// <summary>
    /// 清理所有正在使用的资源。
    /// </summary>
    protected override void Dispose( bool disposing )
    {
    if( disposing )
    {
    if (components != null) 
    {
    components.Dispose();
    }
    }
    base.Dispose( disposing );
    } #region Windows 窗体设计器生成的代码
    /// <summary>
    /// 设计器支持所需的方法 - 不要使用代码编辑器修改
    /// 此方法的内容。
    /// </summary>
    private void InitializeComponent()
    {
    this.textBox1 = new System.Windows.Forms.TextBox();
    this.label1 = new System.Windows.Forms.Label();
    this.button1 = new System.Windows.Forms.Button();
    this.button2 = new System.Windows.Forms.Button();
    this.label2 = new System.Windows.Forms.Label();
    this.SuspendLayout();
    // 
    // textBox1
    // 
    this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
    | System.Windows.Forms.AnchorStyles.Right)));
    this.textBox1.Location = new System.Drawing.Point(16, 16);
    this.textBox1.Name = "textBox1";
    this.textBox1.Size = new System.Drawing.Size(136, 21);
    this.textBox1.TabIndex = 0;
    this.textBox1.Text = "";
    // 
    // label1
    // 
    this.label1.Location = new System.Drawing.Point(64, 48);
    this.label1.Name = "label1";
    this.label1.Size = new System.Drawing.Size(232, 16);
    this.label1.TabIndex = 1;
    // 
    // button1
    // 
    this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
    this.button1.Location = new System.Drawing.Point(160, 16);
    this.button1.Name = "button1";
    this.button1.Size = new System.Drawing.Size(64, 23);
    this.button1.TabIndex = 2;
    this.button1.Text = "计算";
    this.button1.Click += new System.EventHandler(this.button1_Click);
    // 
    // button2
    // 
    this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
    this.button2.Location = new System.Drawing.Point(232, 16);
    this.button2.Name = "button2";
    this.button2.Size = new System.Drawing.Size(64, 23);
    this.button2.TabIndex = 2;
    this.button2.Text = "判断";
    this.button2.Click += new System.EventHandler(this.button2_Click);
    // 
    // label2
    // 
    this.label2.Location = new System.Drawing.Point(24, 48);
    this.label2.Name = "label2";
    this.label2.Size = new System.Drawing.Size(48, 16);
    this.label2.TabIndex = 3;
    this.label2.Text = "结果:";
    // 
    // Form1
    // 
    this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
    this.ClientSize = new System.Drawing.Size(304, 69);
    this.Controls.Add(this.button1);
    this.Controls.Add(this.textBox1);
    this.Controls.Add(this.button2);
    this.Controls.Add(this.label1);
    this.Controls.Add(this.label2);
    this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
    this.MaximizeBox = false;
    this.Name = "Form1";
    this.Text = "Form1";
    this.TopMost = true;
    this.ResumeLayout(false); }
    #endregion /// <summary>
    /// 应用程序的主入口点。
    /// </summary>
    [STAThread]
    static void Main() 
    {
    Application.Run(new Form1());
    } private void button1_Click(object sender, System.EventArgs e)
    {
    try
    {
    this.label1.Text = Calc(this.textBox1.Text).ToString();
    }
    catch(Exception ex)
    {
    MessageBox.Show(ex.ToString());
    }
    } private void button2_Click(object sender, System.EventArgs e)
    {
    try
    {
    this.label1.Text = LogicResult(this.textBox1.Text).ToString();
    }
    catch(Exception ex)
    {
    MessageBox.Show(ex.ToString());
    }
    } public  static  object  Calc(string  expression)  
    {  
    string  className  =  "Calc";  
    string  methodName  =  "Run";  
    expression=expression.Replace("/","*1.0/");
                             
    //  创建编译器实例。  
    ICodeCompiler  complier  =  (new  CSharpCodeProvider().CreateCompiler());  
    //  设置编译参数。  
    CompilerParameters  paras  =  new  CompilerParameters();  
    paras.GenerateExecutable  =  false;  
    paras.GenerateInMemory  =  true;  
     
    //  创建动态代码。  
    StringBuilder  classSource  =  new  StringBuilder();    
    classSource.Append("public  class  "+  className  +"\n");  
    classSource.Append("{\n");  
    classSource.Append("        public  object  "  +  methodName  +  "()\n");  
    classSource.Append("        {\n");  
    classSource.Append("                return  "+  expression  +  ";\n");  
    classSource.Append("        }\n");  
    classSource.Append("}");  
     
    //  编译代码。  
    CompilerResults  result  =  complier.CompileAssemblyFromSource(paras,  classSource.ToString());  
                             
    //  获取编译后的程序集。  
    Assembly  assembly  =  result.CompiledAssembly;   //  动态调用方法。  
    object  eval  =  assembly.CreateInstance(className);  
    MethodInfo  method  =  eval.GetType().GetMethod(methodName);  
    object reobj = method.Invoke(eval,  null);  
    GC.Collect();
    return reobj;
    } public  static  object LogicResult(string  expression)  
    {  
    string  className  =  "Calc";  
    string  methodName  =  "Run";  
    expression=expression.Replace("/","*1.0/");
                             
    //  创建编译器实例。  
    ICodeCompiler  complier  =  (new  CSharpCodeProvider().CreateCompiler());  
    //  设置编译参数。  
    CompilerParameters  paras  =  new  CompilerParameters();  
    paras.GenerateExecutable  =  false;  
    paras.GenerateInMemory  =  true;  
     
    //  创建动态代码。  
    StringBuilder  classSource  =  new  StringBuilder();    
    classSource.Append("public  class  "+  className  +"\n");  
    classSource.Append("{\n");  
    classSource.Append("        public  bool  "  +  methodName  +  "()\n");  
    classSource.Append("        {\n");  
    classSource.Append("                if ("+  expression  +  ") return true; else return false;\n");  
    classSource.Append("        }\n");  
    classSource.Append("}");  
     
    //  编译代码。  
    CompilerResults  result  =  complier.CompileAssemblyFromSource(paras,  classSource.ToString());  
                             
    //  获取编译后的程序集。  
    Assembly  assembly  =  result.CompiledAssembly;  
       
    //  动态调用方法。
    object  eval  =  assembly.CreateInstance(className);  
    MethodInfo  method  =  eval.GetType().GetMethod(methodName);  
    object reobj = method.Invoke(eval,  null);  
    GC.Collect();
    return reobj;
    }
    }
    }
      

  8.   

    XML Web 服务能很好的解决
      

  9.   

    偷懒的办法有两种:
    1、把参数传给远程对象的方法,和把代码从远程传过来执行正好相反,但通常可以达到同样的效果。
    2、在你的系统里嵌一个解释器,比如.net 1.X内置的JS.net或者将要加入.net的IronPython。然后传脚本给它执行。
      

  10.   

    用反射,贴个我今天刚调通的代码,参考了其他前辈的,反射执行string的class代码,实现计算"1+2-3"这样字符串的结果和 判断1 + 2 == 2这样的逻辑表达式是否正确的功能。
    大家提提意见,另外反射调用的东东很难释放,曾看到过用Remoting+反射来执行完就释放的例子,大家可以找找看。
    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.CodeDom.Compiler;
    using Microsoft.CSharp;
    using System.Reflection;
    using System.Text;namespace WindowsApplication1
    {
    /// <summary>
    /// Form1 的摘要说明。
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
    private System.Windows.Forms.TextBox textBox1;
    private System.Windows.Forms.Label label1;
    private System.Windows.Forms.Button button1;
    private System.Windows.Forms.Button button2;
    private System.Windows.Forms.Label label2;
    /// <summary>
    /// 必需的设计器变量。
    /// </summary>
    private System.ComponentModel.Container components = null; public Form1()
    {
    //
    // Windows 窗体设计器支持所必需的
    //
    InitializeComponent(); //
    // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
    //
    } /// <summary>
    /// 清理所有正在使用的资源。
    /// </summary>
    protected override void Dispose( bool disposing )
    {
    if( disposing )
    {
    if (components != null) 
    {
    components.Dispose();
    }
    }
    base.Dispose( disposing );
    } #region Windows 窗体设计器生成的代码
    /// <summary>
    /// 设计器支持所需的方法 - 不要使用代码编辑器修改
    /// 此方法的内容。
    /// </summary>
    private void InitializeComponent()
    {
    this.textBox1 = new System.Windows.Forms.TextBox();
    this.label1 = new System.Windows.Forms.Label();
    this.button1 = new System.Windows.Forms.Button();
    this.button2 = new System.Windows.Forms.Button();
    this.label2 = new System.Windows.Forms.Label();
    this.SuspendLayout();
    // 
    // textBox1
    // 
    this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
    | System.Windows.Forms.AnchorStyles.Right)));
    this.textBox1.Location = new System.Drawing.Point(16, 16);
    this.textBox1.Name = "textBox1";
    this.textBox1.Size = new System.Drawing.Size(136, 21);
    this.textBox1.TabIndex = 0;
    this.textBox1.Text = "";
    // 
    // label1
    // 
    this.label1.Location = new System.Drawing.Point(64, 48);
    this.label1.Name = "label1";
    this.label1.Size = new System.Drawing.Size(232, 16);
    this.label1.TabIndex = 1;
    // 
    // button1
    // 
    this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
    this.button1.Location = new System.Drawing.Point(160, 16);
    this.button1.Name = "button1";
    this.button1.Size = new System.Drawing.Size(64, 23);
    this.button1.TabIndex = 2;
    this.button1.Text = "计算";
    this.button1.Click += new System.EventHandler(this.button1_Click);
    // 
    // button2
    // 
    this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
    this.button2.Location = new System.Drawing.Point(232, 16);
    this.button2.Name = "button2";
    this.button2.Size = new System.Drawing.Size(64, 23);
    this.button2.TabIndex = 2;
    this.button2.Text = "判断";
    this.button2.Click += new System.EventHandler(this.button2_Click);
    // 
    // label2
    // 
    this.label2.Location = new System.Drawing.Point(24, 48);
    this.label2.Name = "label2";
    this.label2.Size = new System.Drawing.Size(48, 16);
    this.label2.TabIndex = 3;
    this.label2.Text = "结果:";
    // 
    // Form1
    // 
    this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
    this.ClientSize = new System.Drawing.Size(304, 69);
    this.Controls.Add(this.button1);
    this.Controls.Add(this.textBox1);
    this.Controls.Add(this.button2);
    this.Controls.Add(this.label1);
    this.Controls.Add(this.label2);
    this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
    this.MaximizeBox = false;
    this.Name = "Form1";
    this.Text = "Form1";
    this.TopMost = true;
    this.ResumeLayout(false); }
    #endregion /// <summary>
    /// 应用程序的主入口点。
    /// </summary>
    [STAThread]
    static void Main() 
    {
    Application.Run(new Form1());
    } private void button1_Click(object sender, System.EventArgs e)
    {
    try
    {
    this.label1.Text = Calc(this.textBox1.Text).ToString();
    }
    catch(Exception ex)
    {
    MessageBox.Show(ex.ToString());
    }
    } private void button2_Click(object sender, System.EventArgs e)
    {
    try
    {
    this.label1.Text = LogicResult(this.textBox1.Text).ToString();
    }
    catch(Exception ex)
    {
    MessageBox.Show(ex.ToString());
    }
    } public  static  object  Calc(string  expression)  
    {  
    string  className  =  "Calc";  
    string  methodName  =  "Run";  
    expression=expression.Replace("/","*1.0/");
                             
    //  创建编译器实例。  
    ICodeCompiler  complier  =  (new  CSharpCodeProvider().CreateCompiler());  
    //  设置编译参数。  
    CompilerParameters  paras  =  new  CompilerParameters();  
    paras.GenerateExecutable  =  false;  
    paras.GenerateInMemory  =  true;  
     
    //  创建动态代码。  
    StringBuilder  classSource  =  new  StringBuilder();    
    classSource.Append("public  class  "+  className  +"\n");  
    classSource.Append("{\n");  
    classSource.Append("        public  object  "  +  methodName  +  "()\n");  
    classSource.Append("        {\n");  
    classSource.Append("                return  "+  expression  +  ";\n");  
    classSource.Append("        }\n");  
    classSource.Append("}");  
     
    //  编译代码。  
    CompilerResults  result  =  complier.CompileAssemblyFromSource(paras,  classSource.ToString());  
                             
    //  获取编译后的程序集。  
    Assembly  assembly  =  result.CompiledAssembly;   //  动态调用方法。  
    object  eval  =  assembly.CreateInstance(className);  
    MethodInfo  method  =  eval.GetType().GetMethod(methodName);  
    object reobj = method.Invoke(eval,  null);  
    GC.Collect();
    return reobj;
    } public  static  object LogicResult(string  expression)  
    {  
    string  className  =  "Calc";  
    string  methodName  =  "Run";  
    expression=expression.Replace("/","*1.0/");
                             
    //  创建编译器实例。  
    ICodeCompiler  complier  =  (new  CSharpCodeProvider().CreateCompiler());  
    //  设置编译参数。  
    CompilerParameters  paras  =  new  CompilerParameters();  
    paras.GenerateExecutable  =  false;  
    paras.GenerateInMemory  =  true;  
     
    //  创建动态代码。  
    StringBuilder  classSource  =  new  StringBuilder();    
    classSource.Append("public  class  "+  className  +"\n");  
    classSource.Append("{\n");  
    classSource.Append("        public  bool  "  +  methodName  +  "()\n");  
    classSource.Append("        {\n");  
    classSource.Append("                if ("+  expression  +  ") return true; else return false;\n");  
    classSource.Append("        }\n");  
    classSource.Append("}");  
     
    //  编译代码。  
    CompilerResults  result  =  complier.CompileAssemblyFromSource(paras,  classSource.ToString());  
                             
    //  获取编译后的程序集。  
    Assembly  assembly  =  result.CompiledAssembly;  
       
    //  动态调用方法。
    object  eval  =  assembly.CreateInstance(className);  
    MethodInfo  method  =  eval.GetType().GetMethod(methodName);  
    object reobj = method.Invoke(eval,  null);  
    GC.Collect();
    return reobj;
    }
    }
    }
      

  11.   

    谢谢大家!
    关于我的需求,我想仔细解释一下。
    我们现在由于特殊需要,要用软件模拟用“移动Agent”实现一种分布式管理的思想——现在仅仅是模拟并评估这种思想,实际系统不是PC上的,也肯定不会用.NET开发。
    所谓“移动Agent”:
    20世纪90年代初,General Magic公司在推出其商业系统Telescript时第一次提出了移动Agent的概念,即一个能在异构网络环境中自主地从一台主机迁移到另一台主机,并可与其它Agent或资源交互的软件实体。移动Agent是一类特殊的软件Agent,它除了具有软件Agent的基本特性--自治性、响应性、主动性和推理性外,还具有移动性,即它可以在网络上从一台主机自主地移动到另一台主机,代表用户完成指定的任务。由于移动Agent可以在异构的软、硬件网络环境中自由移动,因此这种新的计算模式能有效地降低分布式计算中的网络负载、提高通信效率、动态适应变化了的网络环境,并具有很好的安全性和容错能力。
    移动Agent可以看成是软件Agent技术与分布式计算技术相结合的产物,它与传统网络计算模式有着本质上的区别。移动Agent不同于远程过程调用(RPC),这是因为移动Agent能够不断地从网络中的一个节点移动到另一个节点,而且这种移动是可以根据自身需要进行选择的。移动Agent也不同于一般的进程迁移,因为一般来说进程迁移系统不允许进程自己选择什么时候迁移以及迁移到哪里,而移动Agent却可以在任意时刻进行移动,并且可以移动到它想去的任何地方。移动Agent更不同于Java语言中的Applet,因为Applet只能从服务器向客户机做单方向的移动,而移动Agent却可以在客户机和服务器之间进行双向移动。
    以上摘自《移动agent及其应用》,张云勇编著 清华大学出版社,2002据我理解,这种思想最大的好处是,它可以让远端执行一些代码,哪怕这些代码并没有被固化在远端。这在我们的工作中会有用——因为远端设备一旦开始工作,就不能让它停下来修改,而我们在运行中出现的新的需求就不能通过传统修改代码的方式得到满足。
      

  12.   

    看了半天,原来移动Agent就是一个巨型病毒。。
      

  13.   

    如果要实现移动Agent,可不可以把问题简化一些?也就是一个LiveUpdate的问题。
    允许一端接受一个文件,并加载运行不就可以了么?传递代码、再进行编译由什么意义????
    弱设备上是不太可能有编译环境的!简单的方案:一个文件下载程序、一个智能配置程序,一个调度程序,OK。
      

  14.   

    为什么不用asp.net web解决?非要windows form?
      

  15.   

    to adailee(钉子和毛毛虫) :
    是的,我也认为不可以到远端编译。谢谢大家!我今天有些私事,明天仔细学习试验一下大家的方法。谢谢