在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
结合控制台重定向和C#即使编译器(见我上面两篇文章)写的WinForm即时C#编译器,功能还不错。 可以拿下面的代码测试程序
//F5: Compile and Run the app F6:Kill current Running App //----------------------------------------------------------- System.Diagnostics.Process.Start("notepad"); //test Generic Collection List<int> lstInt = new List<int>{ 1,3,5,7,9,11 }; foreach(var v in lstInt) Console.WriteLine(v); //test Timer System.Timers.Timer timer = new System.Timers.Timer(1000); timer.Elapsed += delegate{ System.Console.WriteLine(DateTime.Now.TimeOfDay.ToString()); }; timer.Start(); Console.ReadKey(); //test WinForm Application //Application.Run(new Form());
这个程序用了我两天的时间,涉及到技术有: 实现编译器的代码如下:
//#define CompileIntoMemory using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; namespace PhoenixCompiler { /// <summary> /// director the Console output to ListBox /// in MainForm Construction: /// </summary> public class PhoenixWriter : System.IO.TextWriter { delegate void VoidAction(); System.Windows.Forms.TextBox txtBox; public PhoenixWriter(System.Windows.Forms.TextBox box) { this.txtBox = box; } public override System.Text.Encoding Encoding { get { return System.Text.Encoding.UTF8;} } //here, must use parameter: char value public override void Write(char value) { VoidAction action = delegate{ txtBox.AppendText(value.ToString()); }; txtBox.BeginInvoke(action); } } /// <summary> /// Description of PhoenixCompiler. /// </summary> public class PhoenixCompiler { public PhoenixCompiler() { } public string GenerateCode(string userCode) { string namespaces =@"using System; using System.ComponentModel; using System.Text;using System.Text.RegularExpressions; using System.IO; using System.Collections; using System.Collections.Generic; using System.Windows.Forms ;using System.Threading; using System.Reflection; "; string codeHead = @" sealed class Phoenix { public static void Main() { //----------your code here----------- "; //userCode here string codeTail = @" //----------your code here----------- } } "; string compileCodes = namespaces + codeHead + userCode + codeTail; return compileCodes; } public CompilerResults Compile(string codes) { //CSharpCodeProvider System.CodeDom.Compiler.CodeDomProvider compiler = new Microsoft.CSharp.CSharpCodeProvider(); //CompilerParameters System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters(); parameters.WarningLevel = 4; parameters.ReferencedAssemblies.Add("System.dll"); parameters.ReferencedAssemblies.Add("System.Windows.Forms.dll"); #if CompileIntoMemory parameters.GenerateInMemory = true; #else parameters.GenerateExecutable=true; #endif return compiler.CompileAssemblyFromSource(parameters,codes); } } /// <summary> /// Description of MainForm. /// </summary> public partial class MainForm : Form { System.Diagnostics.Process process; public MainForm() { InitializeComponent(); //redirector Console output to ListBox lstResult Console.SetOut(new PhoenixWriter(txtResult)); } //KillProcessTreeById public void KillProcessTreeById(int parentId) { //find all the process id created by parentId, Saved it to List childIds System.Collections.Generic.List<int> childIds= new System.Collections.Generic.List<int>(); System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcesses(); foreach (var element in processes) { string path = string.Format("win32_process.handle='{0}'",element.Id); using (var mo= new System.Management.ManagementObject(path)) { try { mo.Get(); } catch (System.Management.ManagementException me) { throw me; } int id=Convert.ToInt32(mo["ParentProcessId"]); if (id==parentId) { childIds.Add(element.Id); } } } foreach (var element in childIds) { //Console.WriteLine(element); System.Diagnostics.Process processKill = System.Diagnostics.Process.GetProcessById(element); if (processKill.ProcessName !="conhost") { processKill.Kill(); } //processKill.CloseMainWindow(); //processKill.Close(); } var processParent = System.Diagnostics.Process.GetProcessById(parentId); if (processParent !=null) { processParent.Kill(); } } void TxtCodeKeyDown(object sender, System.Windows.Forms.KeyEventArgs e) {//F5:116 e.KeyCode.ToString() + ":" + e.KeyValue.ToString(); if (e.KeyValue == 116) { if (process!=null) { this.KillProcessTreeById(process.Id); process=null; } PhoenixCompiler compiler = new PhoenixCompiler(); string code = compiler.GenerateCode(txtCode.Text); System.CodeDom.Compiler.CompilerResults result = compiler.Compile(code); ShowResult(result); } if (e.KeyValue==117) {//F6:117 here should terminate the process tree ... ... if (process != null) { this.KillProcessTreeById(process.Id); process=null; } } } public void ShowResult(System.CodeDom.Compiler.CompilerResults result) { txtResult.Text=""; Console.WriteLine("Phoenix Compiler! \r\n\tCopyright by XUMINGHUI(2013)"); Console.WriteLine("-----------------------------------------------\n"); if (result.Errors.HasErrors) { Console.WriteLine("Build ERROR:\r\n"); foreach (System.CodeDom.Compiler.CompilerError error in result.Errors) { Console.WriteLine(error.Line + ":" + error.ErrorText); } return; } //build OK Console.WriteLine("Build Successfully:\r\n"); try {//call Main entry, Console output --> WinForm Control #if CompileIntoMemory Type Phoenix = result.CompiledAssembly.GetType("Phoenix"); Phoenix.GetMethod("Main").Invoke(null,new string[]{}); #else //start another thread to run the generated application System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo{ FileName=result.PathToAssembly, UseShellExecute=false, CreateNoWindow=true, RedirectStandardError=true, RedirectStandardOutput=true }; process = new System.Diagnostics.Process(); process.OutputDataReceived +=(s,e)=>{ if (e.Data!=null) { Console.WriteLine(e.Data); } }; process.ErrorDataReceived +=(s,e)=>{ if (e.Data!=null) { Console.WriteLine(e.Data); } }; process.StartInfo = info; process.EnableRaisingEvents = true; process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); #endif } catch (System.Reflection.TargetInvocationException ex) { Console.WriteLine("Exception:" + ex.InnerException.Message); } } void MainFormFormClosing(object sender, FormClosingEventArgs e) { if (process != null) { this.KillProcessTreeById(process.Id); process=null; } } void TxtResultDoubleClick(object sender, EventArgs e) { if (txtResult.Text=="") { return; } string path = System.IO.Path.GetTempFileName(); System.IO.File.AppendAllText(path,txtResult.Text); System.Diagnostics.Process.Start("notepad",path); } void TxtCodeDoubleClick(object sender, EventArgs e) { PhoenixCompiler compiler = new PhoenixCompiler(); string code = compiler.GenerateCode(txtCode.Text); string path = System.IO.Path.GetTempFileName(); System.IO.File.AppendAllText(path,code); System.Diagnostics.Process.Start("notepad",path); } } }
|
请发表评论