C# 动态加载程序集
定义动态程序集
1 namespace DynamicAssembly 2 { 3 4 public class CodeDriver : MarshalByRefObject 5 { 6 private string prefix = 7 "using System;" + 8 "public static class Driver" + 9 "{" + 10 " public static void Run()" + 11 " {"; 12 13 private string postfix = 14 " }" + 15 "}"; 16 17 18 19 public string CompileAndRun(string input, out bool hasError) 20 { 21 //for (int i = 0; i < 10;i++ ) 22 //{ Console.WriteLine(i); } 23 hasError = false; 24 string returnData = null; 25 26 CompilerResults results = null; 27 using (var provider = new CSharpCodeProvider()) 28 { 29 var options = new CompilerParameters(); 30 options.GenerateInMemory = true; 31 32 var sb = new StringBuilder(); 33 sb.Append(prefix); 34 sb.Append(input); 35 sb.Append(postfix); 36 37 results = provider.CompileAssemblyFromSource(options, sb.ToString()); 38 } 39 40 if (results.Errors.HasErrors) 41 { 42 hasError = true; 43 var errorMessage = new StringBuilder(); 44 foreach (CompilerError error in results.Errors) 45 { 46 errorMessage.AppendFormat("{0} {1}", error.Line, error.ErrorText); 47 } 48 returnData = errorMessage.ToString(); 49 } 50 else 51 { 52 TextWriter temp = Console.Out; 53 var writer = new StringWriter(); 54 Console.SetOut(writer); 55 Type driverType = results.CompiledAssembly.GetType("Driver"); 56 57 driverType.InvokeMember("Run", BindingFlags.InvokeMethod | 58 BindingFlags.Static | BindingFlags.Public, 59 null, null, null); 60 61 Console.SetOut(temp); 62 63 returnData = writer.ToString(); 64 } 65 66 return returnData; 67 } 68 } 69 }
编写调用代码
1 namespace DynamicAssembly 2 { 3 public class CodeDriverInAppDomain 4 { 5 public string CompileAndRun(string code, out bool hasError) 6 { 7 AppDomain codeDomain = AppDomain.CreateDomain("CodeDriver"); 8 9 CodeDriver codeDriver = (CodeDriver) 10 codeDomain.CreateInstanceAndUnwrap("DynamicAssembly", 11 "DynamicAssembly.CodeDriver"); 12 13 string result = codeDriver.CompileAndRun(code, out hasError); 14 15 AppDomain.Unload(codeDomain); 16 17 return result; 18 } 19 20 21 } 22 }
wpf 页面代码
1 <Window x:Class="DynamicAssembly.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="350" Width="525"> 5 <Grid> 6 <Grid.RowDefinitions> 7 <RowDefinition /> 8 <RowDefinition /> 9 </Grid.RowDefinitions> 10 <Grid.ColumnDefinitions> 11 <ColumnDefinition /> 12 <ColumnDefinition Width="Auto" MinWidth="120" /> 13 </Grid.ColumnDefinitions> 14 <TextBox x:Name="textCode" AcceptsReturn="True" AcceptsTab="True" Grid.Row="0" Grid.Column="0" Margin="4" /> 15 <Button Click="Compile_Click" Grid.Row="0" Grid.Column="1" Content="Compile and Run" Margin="5, 10, 5, 10" /> 16 <TextBlock x:Name="textOutput" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="4" /> 17 </Grid> 18 19 </Window>
后台代码
1 private void Compile_Click(object sender, RoutedEventArgs e) 2 { 3 // var custom = new CustomClassDamain(); 4 // string s = custom.CompileAndRun(); 5 6 textOutput.Background = Brushes.White; 7 var driver = new CodeDriverInAppDomain(); 8 bool isError; 9 textOutput.Text = driver.CompileAndRun(textCode.Text, out isError); 10 if (isError) 11 { 12 textOutput.Background = Brushes.Red; 13 } 14 15 16 }
鹰击长空,鱼翔浅底