在c#編寫的軟件中動態地編譯新的代碼

 

首先解釋一下:

這裏用到了幾個類,CodeDomProvider 、CompilerParameters 、CompilerResults 。

CodeDomProvider類提供了我們編譯代碼的容器,我們通過它來工作;

 大家都知道,現在我們要做的是一個很複雜的過程,因爲這個程序要編譯其他人寫的代碼,所以肯定需要配置很多的參數,這時我們就要用到CompilerParameters類;

最後我們生成了最後的exe文件,但那是我們完全正確的時候,如果錯誤了怎麼辦呢?這時我們肯定需要程序給出一個結果,告訴我們我們這個複雜的過程最後造成了什麼樣的“後果”,無論對或錯,總會有個結果啊,這時就用到了 CompilerResults 類。

這裏的textBox2用來顯示最後的結果,是成功了,還是失敗了,失敗的話會有錯誤信息;textBox1是要執行的代碼,我們可以在運行是複製過來。

下面是我的代碼:

            //CodeDomProvider 可用於創建和檢索代碼生成器和代碼編譯器的實例。

            //代碼生成器可用於以特定的語言生成代碼,而代碼編譯器可用於將代碼編譯爲程序集.

            CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");//指定編程語言

            string Output = "Out.exe";//指定最後產生的程序的名字,它將和我們這個程序在一個目錄下

            textBox2.Text = "";

            //表示用於調用編譯器的參數

            System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();

            //獲取或設置一個值,該值指示是否生成可執行文件。true表示EXE, false表示 DLL

            parameters.GenerateExecutable = true;

            //獲取或設置輸出程序集的名稱。

            parameters.OutputAssembly = Output;

            //獲取或設置一個值,該值指示是否在已編譯的可執行文件中包含調試信息。

            parameters.IncludeDebugInformation = true;

            //獲取當前項目所引用的程序集。根據具體需要添加

            parameters.ReferencedAssemblies.Add("system.dll");

            parameters.ReferencedAssemblies.Add("system.data.dll");

            parameters.ReferencedAssemblies.Add("system.Drawing.dll");

            parameters.ReferencedAssemblies.Add("system.Windows.Forms.dll");

            parameters.ReferencedAssemblies.Add("Interop.IWshRuntimeLibrary.dll");

            //CompileAssemblyFromSource方法從包含源代碼的字符串的指定數組,使用指定的編譯器設置編譯程序集。

            //CompilerResults表示從編譯器返回的編譯結果

            CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, textBox1.Text);

            //獲取編譯器錯誤和警告的個數

            if (results.Errors.Count > 0)

            {

                foreach (CompilerError CompErr in results.Errors)

                {

                    textBox2.Text = textBox2.Text +

                                "Line number " + CompErr.Line +

                                ", Error Number: " + CompErr.ErrorNumber +

                                ", '" + CompErr.ErrorText + ";" +

                                Environment.NewLine + Environment.NewLine;

                }

            }

            else

            {

                //成功了

                textBox2.Text = "Success!";

                //執行這個程序

                //Process.Start(Output);

            }

不好意思,再解釋一下,這裏我們添加了好多的dll文件,因爲是我這裏要編譯的代碼需要的,如果要編譯的很簡單可能就不需要這些。

下面是我要編譯的代碼,是一個在windows下開機自動進行adsl撥號的代碼。

 

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Runtime.InteropServices;

using IWshRuntimeLibrary;

namespace AutoConnectAdsl

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

 

        private void Form1_Load(object sender, EventArgs e)

        {

            RASDisplay d = new RASDisplay();

            if (d.IsConnected == false)

            {

                d.Connect("adsl");

            }

            this.Close();

            SetThisToStart();

        }

 

        /// <summary>

        /// 創建該程序的快捷方式到啓動菜單

        /// </summary>

        private void SetThisToStart()

        {

            WshShell shell = new WshShell();

            string StartupPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Startup);

            IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(StartupPath + "//AutoADSL.lnk");

            shortcut.TargetPath = System.Reflection.Assembly.GetExecutingAssembly().Location;

            shortcut.WorkingDirectory = System.Environment.CurrentDirectory;

            shortcut.WindowStyle = 1;

            shortcut.Description = "AutoADSL";

            shortcut.IconLocation = System.Environment.SystemDirectory + "" + "shell32.dll, 165";

            shortcut.Save();

        }

    }

}

namespace AutoConnectAdsl

{

    partial class Form1

    {

        /// <summary>

        /// 必需的設計器變量。

        /// </summary>

        private System.ComponentModel.IContainer components = null;

 

        /// <summary>

        /// 清理所有正在使用的資源。

        /// </summary>

        /// <param name="disposing">如果應釋放託管資源,爲 true;否則爲 false。</param>

        protected override void Dispose(bool disposing)

        {

            if (disposing && (components != null))

            {

                components.Dispose();

            }

            base.Dispose(disposing);

        }

 

        #region Windows 窗體設計器生成的代碼

 

        /// <summary>

        /// 設計器支持所需的方法 - 不要

        /// 使用代碼編輯器修改此方法的內容。

        /// </summary>

        private void InitializeComponent()

        {

            this.SuspendLayout();

            // 

            // Form1

            // 

            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);

            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;

            this.ClientSize = new System.Drawing.Size(292, 266);

            this.Name = "Form1";

            this.Text = "Form1";

            this.Load += new System.EventHandler(this.Form1_Load);

            this.ResumeLayout(false);

        }

 

        #endregion

 

    }

}

namespace AutoConnectAdsl

{

    public struct RASCONN

    {

        public int dwSize;

        public IntPtr hrasconn;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 257)]

        public string szEntryName;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 17)]

        public string szDeviceType;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 129)]

        public string szDeviceName;

    }

 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

    public struct RasStats

    {

        public int dwSize;

        public int dwBytesXmited;

        public int dwBytesRcved;

        public int dwFramesXmited;

        public int dwFramesRcved;

        public int dwCrcErr;

        public int dwTimeoutErr;

        public int dwAlignmentErr;

        public int dwHardwareOverrunErr;

        public int dwFramingErr;

        public int dwBufferOverrunErr;

        public int dwCompressionRatioIn;

        public int dwCompressionRatioOut;

        public int dwBps;

        public int dwConnectionDuration;

    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

    public struct RasEntryName

    {

        public int dwSize;

        //[MarshalAs(UnmanagedType.ByValTStr,SizeConst=(int)RasFieldSizeConstants.RAS_MaxEntryName + 1)]

        public string szEntryName;

        //#if WINVER5

        //  public int dwFlags;

        //  [MarshalAs(UnmanagedType.ByValTStr,SizeConst=260+1)]

        //  public string szPhonebookPath;

        //#endif

    }

    public class RAS

    {

        [DllImport("Rasapi32.dll", EntryPoint = "RasEnumConnectionsA",

             SetLastError = true)]

        internal static extern int RasEnumConnections

            (

            ref RASCONN lprasconn, // buffer to receive connections data

            ref int lpcb, // size in bytes of buffer

            ref int lpcConnections // number of connections written to buffer

            );

        [DllImport("rasapi32.dll", CharSet = CharSet.Auto)]

        internal static extern uint RasGetConnectionStatistics(

            IntPtr hRasConn,       // handle to the connection

            [In, Out]RasStats lpStatistics  // buffer to receive statistics

            );

        [DllImport("rasapi32.dll", CharSet = CharSet.Auto)]

        public extern static uint RasHangUp(

            IntPtr hrasconn  // handle to the RAS connection to hang up

            );

        [DllImport("rasapi32.dll", CharSet = CharSet.Auto)]

        public extern static uint RasEnumEntries(

            string reserved,              // reserved, must be NULL

            string lpszPhonebook,         // pointer to full path and

            //  file name of phone-book file

            [In, Out]RasEntryName[] lprasentryname, // buffer to receive

            //  phone-book entries

            ref int lpcb,                  // size in bytes of buffer

            out int lpcEntries             // number of entries written

            //  to buffer

            );

        [DllImport("wininet.dll", CharSet = CharSet.Auto)]

        public extern static int InternetDial(

            IntPtr hwnd,

            [In]string lpszConnectoid,

            uint dwFlags,

            ref int lpdwConnection,

            uint dwReserved

            );

        public RAS()

        {

        }

    }

    public enum DEL_CACHE_TYPE //要刪除的類型。

    {

        File,//表示internet臨時文件

        Cookie //表示Cookie

    }

}

namespace AutoConnectAdsl

{

    public class RASDisplay

    {

        [DllImport("wininet.dll", CharSet = CharSet.Auto)]

        public static extern bool DeleteUrlCacheEntry(

            DEL_CACHE_TYPE type

            );

        private string m_duration;

        private string m_ConnectionName;

        private string[] m_ConnectionNames;

        private double m_TX;

        private double m_RX;

        private bool m_connected;

        private IntPtr m_ConnectedRasHandle;

        RasStats status = new RasStats();

        public RASDisplay()

        {

            m_connected = true;

            RAS lpras = new RAS();

            RASCONN lprasConn = new RASCONN();

            lprasConn.dwSize = Marshal.SizeOf(typeof(RASCONN));

            lprasConn.hrasconn = IntPtr.Zero;

            int lpcb = 0;

            int lpcConnections = 0;

            int nRet = 0;

            lpcb = Marshal.SizeOf(typeof(RASCONN));

            nRet = RAS.RasEnumConnections(ref lprasConn, ref lpcb, ref

            lpcConnections);

            if (nRet != 0)

            {

                m_connected = false;

                return;

            }

            try

            {

                if (lpcConnections == 0)

                {

                    m_connected = false;

                }

            }

            catch(Exception e)

            {

 

            }       

            int lpNames = 1;

            int entryNameSize = 0;

            int lpSize = 0;

            RasEntryName[] names = null;

            entryNameSize = Marshal.SizeOf(typeof(RasEntryName));

            lpSize = lpNames * entryNameSize;

            names = new RasEntryName[lpNames];

            names[0].dwSize = entryNameSize;

            uint retval = RAS.RasEnumEntries(null, null, names, ref lpSize, out lpNames);

            //if we have more than one connection, we need to do it again

            if (lpNames > 1)

            {

                names = new RasEntryName[lpNames];

                for (int i = 0; i < names.Length; i++)

                {

                    names[i].dwSize = entryNameSize;

                }

 

                retval = RAS.RasEnumEntries(null, null, names, ref lpSize, out lpNames);

 

            }

            m_ConnectionNames = new string[names.Length];

 

 

            if (lpNames > 0)

            {

                for (int i = 0; i < names.Length; i++)

                {

                    m_ConnectionNames[i] = names[i].szEntryName;

                }

            }

        }

 

        public string Duration

        {

            get

            {

                return m_connected ? m_duration : "";

            }

        }

 

        public string[] Connections

        {

            get

            {

                return m_ConnectionNames;

            }

        }

 

        public double BytesTransmitted

        {

            get

            {

                return m_connected ? m_TX : 0;

            }

        }

        public double BytesReceived

        {

            get

            {

                return m_connected ? m_RX : 0;

 

            }

        }

        public string ConnectionName

        {

            get

            {

                return m_connected ? m_ConnectionName : "";

            }

        }

        public bool IsConnected

        {

            get

            {

                return m_connected;

            }

        }

 

        public int Connect(string Connection)

        {

            int temp = 0;

            uint INTERNET_AUTO_DIAL_UNATTENDED = 2;

            int retVal = RAS.InternetDial(IntPtr.Zero, Connection, INTERNET_AUTO_DIAL_UNATTENDED, ref temp, 0);

            return retVal;

        }

        public void Disconnect()

        {

            RAS.RasHangUp(m_ConnectedRasHandle);

        }

    }

}

namespace AutoConnectAdsl

{

    static class Program

    {

        /// <summary>

        /// 應用程序的主入口點。

        /// </summary>

        [STAThread]

        static void Main()

        {

            Application.EnableVisualStyles();

            Application.SetCompatibleTextRenderingDefault(false);

            Application.Run(new Form1());

        }

    }

}

提供源碼下載:

 

http://download.csdn.net/source/1730039

發佈了101 篇原創文章 · 獲贊 3 · 訪問量 28萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章