首先解釋一下:
這裏用到了幾個類,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());
}
}
}
提供源碼下載: