如何使用动态编译的自定义类

时间:2016-05-07 09:46:26

标签: c# dynamic compilation

我有一个动态编译的表单,我有一个样式类。当我将这个样式类复制到我的表单源并编译它时,一切正常。但是我如何使用这个样式类而不将其复制到我的表单源。我编译此表单的主程序有这个类,我该如何使用它?也许我可以将样式类传递给它,因为我编译它,就像var?

节目来源:

using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using Microsoft.CSharp;

namespace dynamic
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            new Thread(newForm).Start();
        }

        public void newForm()
        {
            using (CSharpCodeProvider provider = new CSharpCodeProvider(new Dictionary<string, string>
                {
                    {"CompilerVersion", "v4.0"}
                }))
            {

                var parameters = new CompilerParameters
                {
                    GenerateExecutable = false, // Create a dll
                    GenerateInMemory = true, // Create it in memory
                    WarningLevel = 3, // Default warning level
                    CompilerOptions = "/optimize", // Optimize code
                    TreatWarningsAsErrors = false // Better be false to avoid break in warnings
                };

                parameters.ReferencedAssemblies.Add("mscorlib.dll");
                parameters.ReferencedAssemblies.Add("System.dll");
                parameters.ReferencedAssemblies.Add("System.Core.dll");
                parameters.ReferencedAssemblies.Add("System.Data.dll");
                parameters.ReferencedAssemblies.Add("System.Drawing.dll");
                parameters.ReferencedAssemblies.Add("System.Xml.dll");
                parameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");

                var source = File.ReadAllText("form.txt");
                CompilerResults results = provider.CompileAssemblyFromSource(parameters, source);
                Type type = results.CompiledAssembly.GetType("myForm.Form1");
                object compiledObject = Activator.CreateInstance(type);

                type.GetMethod("ShowDialog", new Type[0]).Invoke(compiledObject, new object[] {});

                MessageBox.Show("formClosed");
            }
        }
    }
}

样式文件夹: enter image description here

表单来源:

using System;
using System.Windows.Forms;

namespace myForm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            var newTmr = new Timer { Interval = 1000 };
            newTmr.Tick += count;
            newTmr.Enabled = true;
        }

        private void count(Object myObject, EventArgs myEventArgs)
        {
            timer.Value2 = (Int32.Parse(timer.Value2) + 1).ToString();
        }

        private void button1_Click(object sender, System.EventArgs e)
        {
            MessageBox.Show("clicked");
        }

        private void nsButton1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("button");
        }
    }
}
namespace myForm
{
    partial class Form1
    {
        /// <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.nsTheme1 = new myForm.NSTheme();
            this.nsButton1 = new myForm.NSButton();
            this.timer = new myForm.NSLabel();
            this.nsControlButton1 = new myForm.NSControlButton();
            this.nsTheme1.SuspendLayout();
            this.SuspendLayout();
            // 
            // nsTheme1
            // 
            this.nsTheme1.AccentOffset = 0;
            this.nsTheme1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(50)))), ((int)(((byte)(50)))));
            this.nsTheme1.BorderStyle = System.Windows.Forms.FormBorderStyle.None;
            this.nsTheme1.Colors = new myForm.Bloom[0];
            this.nsTheme1.Controls.Add(this.nsControlButton1);
            this.nsTheme1.Controls.Add(this.timer);
            this.nsTheme1.Controls.Add(this.nsButton1);
            this.nsTheme1.Customization = "";
            this.nsTheme1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.nsTheme1.Font = new System.Drawing.Font("Verdana", 8F);
            this.nsTheme1.Image = null;
            this.nsTheme1.Location = new System.Drawing.Point(0, 0);
            this.nsTheme1.Movable = true;
            this.nsTheme1.Name = "nsTheme1";
            this.nsTheme1.NoRounding = false;
            this.nsTheme1.Sizable = true;
            this.nsTheme1.Size = new System.Drawing.Size(284, 274);
            this.nsTheme1.SmartBounds = true;
            this.nsTheme1.StartPosition = System.Windows.Forms.FormStartPosition.WindowsDefaultLocation;
            this.nsTheme1.TabIndex = 0;
            this.nsTheme1.Text = "nsTheme1";
            this.nsTheme1.TransparencyKey = System.Drawing.Color.Empty;
            this.nsTheme1.Transparent = false;
            // 
            // nsButton1
            // 
            this.nsButton1.Location = new System.Drawing.Point(100, 166);
            this.nsButton1.Name = "nsButton1";
            this.nsButton1.Size = new System.Drawing.Size(75, 23);
            this.nsButton1.TabIndex = 0;
            this.nsButton1.Text = "nsButton1";
            this.nsButton1.Click += new System.EventHandler(this.nsButton1_Click);
            // 
            // timer
            // 
            this.timer.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Bold);
            this.timer.Location = new System.Drawing.Point(91, 82);
            this.timer.Name = "timer";
            this.timer.Size = new System.Drawing.Size(101, 23);
            this.timer.TabIndex = 1;
            this.timer.Text = "nsLabel1";
            this.timer.Value1 = "Timer: ";
            this.timer.Value2 = "0";
            // 
            // nsControlButton1
            // 
            this.nsControlButton1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.nsControlButton1.ControlButton = myForm.NSControlButton.Button.Close;
            this.nsControlButton1.Location = new System.Drawing.Point(262, 4);
            this.nsControlButton1.Margin = new System.Windows.Forms.Padding(0);
            this.nsControlButton1.MaximumSize = new System.Drawing.Size(18, 20);
            this.nsControlButton1.MinimumSize = new System.Drawing.Size(18, 20);
            this.nsControlButton1.Name = "nsControlButton1";
            this.nsControlButton1.Size = new System.Drawing.Size(18, 20);
            this.nsControlButton1.TabIndex = 2;
            this.nsControlButton1.Text = "nsControlButton1";
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(284, 274);
            this.Controls.Add(this.nsTheme1);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            this.Name = "Form1";
            this.Text = "Form1";
            this.nsTheme1.ResumeLayout(false);
            this.ResumeLayout(false);

        }

        #endregion

        private NSTheme nsTheme1;
        private NSButton nsButton1;
        private NSControlButton nsControlButton1;
        private NSLabel timer;
    }
}

样式来源: http://pastebin.com/CjmQQ9ND

项目来源 - https://yadi.sk/d/ChtMacrsraD4g 如果你编译这个源代码,一切都会正常工作。那是因为我在form.txt文件中使用了样式。我在form.txt文件中将表单与样式分开。我在我的主程序中有这种风格(你可以在屏幕截图中看到)。如何将此样式类发送到动态编译的表单,因此表单可以使用它。

3 个答案:

答案 0 :(得分:4)

您应该能够简单地将样式附加到源:

var source = File.ReadAllText("form.txt");

source += Environment.NewLine;
source += File.ReadAllText("style.txt");

答案 1 :(得分:1)

在Form.txt文件中而不是按顺序排列宏:

namespace myForm
{
<%THEME%>
}

namespace myForm
{
<%THEMEBASE%>
}

在编译之前,加载样式文件并以代码形式替换它们:

//Load style files
var NSThemeSource = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\Class\Style\NSTheme.cs"));
var themeBaseSource = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\Class\Style\ThemeBase154.cs"));
var source = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Form.txt"));

//Substitute in the form styles
source = source.Replace("<%THEME%>", NSThemeSource);
source = source.Replace("<%THEMEBASE%>", themeBaseSource);

<强> P.S。 您可以在Embedded Resource中切换样式文件的构建操作,以便从exe获取样式类。 并使用此助手 - http://www.vcskicks.com/embedded-resource.php

您需要将代码更改为:

var NSThemeSource = ResourceHelper.GetEmbeddedResource("Class/Style/NSTheme.cs");
var themeBaseSource = ResourceHelper.GetEmbeddedResource("Class/Style/ThemeBase154.cs");

答案 2 :(得分:1)

首先,您需要在NSTheme.cs和ThemeBase154.cs中创建类,枚举等 public 。 (最好放入一些命名空间,而不是将它们放在全局(动态)命名空间中)。

然后,添加parameters.ReferencedAssemblies.Add(&#34; dynamic.exe&#34;);你的exe文件(你可能想把你的样式放在一个单独的DLL中)。

之后,在您的form.txt中添加using dynamic;并从new myForm.NSTheme()中移除限定符(因此,它变为new NSTheme())。

现在,您可以使用自己的样式,而无需将其复制到表单类中。

如果您遗漏了某些内容,请检查CompilerResults results错误是否存在特定问题。