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

📄 csharpbindingcompilermanager.cs

📁 c#源代码
💻 CS
📖 第 1 页 / 共 2 页
字号:
// <file>
//     <copyright see="prj:///doc/copyright.txt"/>
//     <license see="prj:///doc/license.txt"/>
//     <owner name="Mike Krueger" email="mike@icsharpcode.net"/>
//     <version value="$version"/>
// </file>

using System;
using System.Collections;
using System.IO;
using System.Diagnostics;
using System.Text;
using System.Text.RegularExpressions;
using System.CodeDom.Compiler;

using ICSharpCode.Core.Services;

using ICSharpCode.SharpDevelop.Internal.Project;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Services;

namespace CSharpBinding
{
	/// <summary>
	/// This class controls the compilation of C Sharp files and C Sharp projects
	/// </summary>
	public class CSharpBindingCompilerManager
	{
		FileUtilityService fileUtilityService = (FileUtilityService)ServiceManager.Services.GetService(typeof(FileUtilityService));
		
		// we have 2 formats for the error output the csc gives :
		readonly static Regex normalError  = new Regex(@"(?<file>.*)\((?<line>\d+),(?<column>\d+)\):\s+(?<error>\w+)\s+(?<number>[\d\w]+):\s+(?<message>.*)", RegexOptions.Compiled);
		readonly static Regex generalError = new Regex(@"(?<error>.+?)\s+(?<number>[\d\w]+?):\s+(?<message>.*)", RegexOptions.Compiled);
		
		readonly static Regex monoNormalError = new Regex(@"(?<file>.*)\((?<line>\d+)\)\s+(?<error>\w+)\s+(?<number>[\d\w]+):\s+(?<message>.*)", RegexOptions.Compiled);
		
		public string GetCompiledOutputName(string fileName)
		{
			return Path.ChangeExtension(fileName, ".exe");
		}
		
		public string GetCompiledOutputName(IProject project)
		{
			CSharpProject p = (CSharpProject)project;
			return GetCompiledOutputName((CSharpCompilerParameters)p.ActiveConfiguration);
		}
		
		public bool CanCompile(string fileName)
		{
			return Path.GetExtension(fileName).ToUpper() == ".CS";
		}
		
		string GenerateOptions(CSharpCompilerParameters compilerparameters, string outputFileName)
		{
			StringBuilder sb = new StringBuilder();
			
			sb.Append("\"/out:");sb.Append(outputFileName);sb.Append('"');sb.Append(Environment.NewLine);
			
			sb.Append("/nologo");sb.Append(Environment.NewLine);
			sb.Append("/utf8output");sb.Append(Environment.NewLine);
			sb.Append("/w:");sb.Append(compilerparameters.WarningLevel);sb.Append(Environment.NewLine);
			
			if (compilerparameters.NoWarnings != null && compilerparameters.NoWarnings.Trim().Length > 0) {
				sb.Append("/nowarn:");sb.Append(compilerparameters.NoWarnings.Trim());sb.Append(Environment.NewLine);
			}
			
			if (compilerparameters.Debugmode) {
				sb.Append("/debug:+");sb.Append(Environment.NewLine);
				sb.Append("/debug:full");sb.Append(Environment.NewLine);
				sb.Append("/d:DEBUG");sb.Append(Environment.NewLine);
			}
			
			if (compilerparameters.Optimize) {
				sb.Append("/o");sb.Append(Environment.NewLine);
			}
			
			if (compilerparameters.Win32Icon != null && compilerparameters.Win32Icon.Trim().Length > 0 && File.Exists(compilerparameters.Win32Icon.Trim())) {
				sb.Append("\"/win32icon:");sb.Append(compilerparameters.Win32Icon.Trim());sb.Append("\"");sb.Append(Environment.NewLine);
			}
			
			if (compilerparameters.UnsafeCode) {
				sb.Append("/unsafe");sb.Append(Environment.NewLine);
			}
			
			if (compilerparameters.NoStdLib) {
				sb.Append("/nostdlib+");sb.Append(Environment.NewLine);
			}
			
			if (compilerparameters.DefineSymbols != null && compilerparameters.DefineSymbols.Trim().Length > 0) {
				sb.Append("/define:");sb.Append('"');sb.Append(compilerparameters.DefineSymbols);sb.Append('"');sb.Append(Environment.NewLine);
			}
			
			if (compilerparameters.MainClass != null && compilerparameters.MainClass.Trim().Length > 0) {
				sb.Append("/main:");sb.Append(compilerparameters.MainClass.Trim());sb.Append(Environment.NewLine);
			}
			
			switch (compilerparameters.CompileTarget) {
				case CompileTarget.Exe:
					sb.Append("/t:exe");
					break;
				case CompileTarget.WinExe:
					sb.Append("/t:winexe");
					break;
				case CompileTarget.Library:
					sb.Append("/t:library");
					break;
				case CompileTarget.Module:
					sb.Append("/t:module");
					break;					
				default:
					throw new NotSupportedException("unknown compile target:" + compilerparameters.CompileTarget);
			}
			sb.Append(Environment.NewLine);
			
			if (compilerparameters.GenerateXmlDocumentation) {
				sb.Append("\"/doc:");sb.Append(Path.ChangeExtension(outputFileName, ".xml"));sb.Append('"');sb.Append(Environment.NewLine);
			}
			
			return sb.ToString();
		}
		
		public ICompilerResult CompileFile(string filename, CSharpCompilerParameters compilerparameters)
		{
			string output = "";
			string error  = "";
			string exe = Path.ChangeExtension(filename, ".exe");
			if (compilerparameters.OutputAssembly != null && compilerparameters.OutputAssembly.Length > 0) {
				exe = compilerparameters.OutputAssembly;
			}
			string responseFileName = Path.GetTempFileName();
			
			StreamWriter writer = new StreamWriter(responseFileName);
			writer.WriteLine(GenerateOptions(compilerparameters, exe));
			writer.WriteLine('"' + filename + '"');
			writer.Close();
			
			string compilerFileName = GetCompilerFileName(compilerparameters);
			string outstr =  String.Concat(compilerFileName, " \"@", responseFileName, "\"");
			TempFileCollection  tf = new TempFileCollection ();
			Executor.ExecWaitWithCapture(outstr, tf, ref output, ref error);
			
			ICompilerResult result = ParseOutput(tf, output, true);
			
			File.Delete(responseFileName);
			File.Delete(output);
			File.Delete(error);
			WriteManifestFile(exe);
			return result;
		}
		
		public ICompilerResult CompileProject(IProject project)
		{
			CSharpProject p = (CSharpProject)project;
			CSharpCompilerParameters compilerparameters = (CSharpCompilerParameters)p.ActiveConfiguration;
			
			string exe              = GetCompiledOutputName(compilerparameters);
			string responseFileName = Path.GetTempFileName();
			
			foreach (ProjectFile finfo in project.ProjectFiles) {
				if (Path.GetFileName(finfo.Name).ToLower() == "app.config") {
					try {
						File.Copy(finfo.Name, exe + ".config", true);
					} catch (Exception ex) {
						IMessageService messageService =(IMessageService)ServiceManager.Services.GetService(typeof(IMessageService));
						messageService.ShowError(ex);
					}
					break;
				}
			}
			
			StreamWriter writer = new StreamWriter(responseFileName);
			if (compilerparameters.CsharpCompiler == CsharpCompiler.Csc) {
				writer.WriteLine(GenerateOptions(compilerparameters, exe));
								
				// write references
				foreach (ProjectReference lib in p.ProjectReferences) {
					string fileName = lib.GetReferencedFileName(p);
					if (fileName != null) {
						if (IsNetModule(fileName)) {
							writer.WriteLine(String.Concat("\"/addmodule:", fileName, "\""));
						} else { 	
							writer.WriteLine(String.Concat("\"/r:", fileName, "\""));
						}
					} else {
						throw new InvalidProjectReferenceFileNameException(lib);
					}
				}
				
				// write source files and embedded resources
				foreach (ProjectFile finfo in p.ProjectFiles) {
					if (finfo.Subtype != Subtype.Directory) {
						switch (finfo.BuildAction) {
							case BuildAction.Compile:
								writer.WriteLine(String.Concat('"', finfo.Name, '"'));
								break;
							case BuildAction.EmbedAsResource:
								writer.WriteLine(String.Concat("\"/res:", finfo.Name, "\""));
								break;
						}
					}
				}
			} else {
				writer.WriteLine(GenerateMonoOptions(compilerparameters, exe));

				IProjectService projectService = (IProjectService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(IProjectService));
				
				foreach (ProjectReference lib in p.ProjectReferences) {
					string fileName = lib.GetReferencedFileName(p);
					if (fileName != null) {
						if (IsNetModule(fileName)) {
							writer.WriteLine(String.Concat("\"/addmodule:", fileName, "\""));
						} else { 	
							writer.WriteLine(String.Concat("\"/r:", fileName, "\""));
						}
					} else {
						throw new InvalidProjectReferenceFileNameException(lib);
					}
				}
				
				foreach (ProjectFile finfo in p.ProjectFiles) {
					if (finfo.Subtype != Subtype.Directory) {
						switch (finfo.BuildAction) {
							case BuildAction.Compile:
								writer.WriteLine(String.Concat('"', finfo.Name, '"'));
								break;
								
							case BuildAction.EmbedAsResource:
								writer.WriteLine(String.Concat("-res:\"", finfo.Name, "\""));
								break;
						}
					}
				}
			}
			writer.Close();
			
			string output = String.Empty;
			string error  = String.Empty;
			
			string compilerFileName = GetCompilerFileName(compilerparameters);
			

⌨️ 快捷键说明

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