⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scriptrunner.cs

📁 c#源代码
💻 CS
字号:
// <file>
//     <copyright see="prj:///doc/copyright.txt"/>
//     <license see="prj:///doc/license.txt"/>
//     <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
//     <version value="$version"/>
// </file>

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Reflection;
using System.Diagnostics;
using System.Resources;
using System.Windows.Forms;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.IO;
using System.CodeDom.Compiler;

using ICSharpCode.Core.Services;

namespace ICSharpCode.SharpDevelop.Internal.Templates
{
	public class ScriptRunner
	{
		FileTemplate item;
		FileDescriptionTemplate file;
		
		readonly static Regex scriptRegex  = new Regex("<%.*?%>");
		readonly static Regex replaceRegex = new Regex("\"");
		
		public string CompileScript(FileTemplate item, FileDescriptionTemplate file)
		{
			Match m = scriptRegex.Match(file.Content);
			m = m.NextMatch();
			if (m.Success) {
				this.item = item;
				this.file = file;
				return CompileAndGetOutput(GenerateCode());
			}
			return file.Content;
		}
		
		// TODO: AppDomain loading !!!5
		byte[] GetBytes(string fileName)
		{
			using (FileStream fs = new FileStream(fileName, FileMode.Open)) {
				long size = fs.Length;
				byte[] outArray = new byte[size];
				fs.Read(outArray, 0, (int)size);
				fs.Close();
				return outArray;
			}
		}
		
		string CompileAndGetOutput(string fileContent)
		{
			TempFileCollection  tf = new TempFileCollection ();
			
			string path = Path.Combine(tf.BasePath, tf.TempDir);
			Directory.CreateDirectory(path);
			string generatedScript = Path.Combine(path, "InternalGeneratedScript.cs");
			string generatedDLL    = Path.Combine(path, "A.DLL");
			tf.AddFile(generatedScript, false);
			tf.AddFile(generatedDLL, false);
			
			StreamWriter sw = new StreamWriter(generatedScript);
			sw.Write(fileContent);
			sw.Close();
			
			string output = String.Empty;
			string error  = String.Empty;
			
			Executor.ExecWaitWithCapture(GetCompilerName() + " /target:library \"/out:" + generatedDLL + "\" \"" + generatedScript +"\"", tf, ref output, ref error);
			
			if (!File.Exists(generatedDLL)) {
				IMessageService messageService =(IMessageService)ServiceManager.Services.GetService(typeof(IMessageService));
				StreamReader sr = File.OpenText(output);
				string errorMessage = sr.ReadToEnd();
				sr.Close();
				messageService.ShowMessage(errorMessage);
				return ">>>>ERROR IN CODE GENERATION GENERATED SCRIPT WAS:\n" + fileContent + "\n>>>>END";
			}
			
			Assembly asm = Assembly.Load(GetBytes(generatedDLL));
			
			object templateInstance = asm.CreateInstance("Template");
			StringParserService stringParserService = (StringParserService)ServiceManager.Services.GetService(typeof(StringParserService));
			
			foreach (TemplateProperty property in item.Properties) {
				FieldInfo fieldInfo = templateInstance.GetType().GetField(property.Name);
				fieldInfo.SetValue(templateInstance, Convert.ChangeType(stringParserService.Properties["Properties." + property.Name], property.Type.StartsWith("Types:") ? typeof(string): Type.GetType(property.Type)));
			}
			MethodInfo methodInfo = templateInstance.GetType().GetMethod("GenerateOutput");
			string ret = methodInfo.Invoke(templateInstance, null).ToString();
			tf.Delete();
			return ret;
		}
		
		string GetCompilerName()
		{
			string runtimeDirectory = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();
			return String.Concat('"', Path.Combine(runtimeDirectory, "csc.exe"), '"');
		}
		
		string GenerateCode()
		{
			StringBuilder outPut = new StringBuilder();
			int lastIndex = 0;
			outPut.Append("public class Template {\n");
			foreach (TemplateProperty property in item.Properties) {
				outPut.Append("public ");
				// internal generated enum types are nothing other than strings
				if (property.Type.StartsWith("Types:")) {
					outPut.Append("string");
				} else {
					outPut.Append(property.Type);
				}
				outPut.Append(' ');
				outPut.Append(property.Name);
				outPut.Append(";\n");
			}
			outPut.Append("public string GenerateOutput() {\n");
			outPut.Append("System.Text.StringBuilder outPut = new System.Text.StringBuilder();\n");
			
			for (Match m = scriptRegex.Match(file.Content); m.Success; m = m.NextMatch()) {
				Group g = m.Groups[0];
				outPut.Append("outPut.Append(@\"");
				outPut.Append(file.Content.Substring(lastIndex, g.Index - lastIndex));
				outPut.Append("\");\n");
				outPut.Append(g.Value.Substring(2, g.Length - 4));
				lastIndex = g.Index + g.Length;
			}
			outPut.Append("outPut.Append(@\"");
			string formattedContent = replaceRegex.Replace(file.Content.Substring(lastIndex, file.Content.Length - lastIndex), "\"\"");
			outPut.Append(formattedContent);
			outPut.Append("\");\n");
			outPut.Append("return outPut.ToString();\n");
			outPut.Append("}}\n");
			return outPut.ToString();
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -