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

📄 defaultprojectservice.cs

📁 全功能c#编译器
💻 CS
📖 第 1 页 / 共 2 页
字号:
// <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.Reflection;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Xml;
using System.CodeDom.Compiler;

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

using ICSharpCode.Core.Properties;
using ICSharpCode.Core.Services;

namespace ICSharpCode.SharpDevelop.Services
{
	
	public enum BeforeCompileAction {
		Nothing,
		SaveAllFiles,
		PromptForSave,
	}
	
	public class DefaultProjectService : AbstractService, IProjectService
	{
		IProject currentProject = null;
		Combine  currentCombine = null;
		Combine  openCombine    = null;
		
		string   openCombineFileName = null;
		
		public IProject CurrentSelectedProject {
			get {
				return currentProject;
			}
			set {
				System.Diagnostics.Debug.Assert(openCombine != null);
				currentProject = value;
				OnCurrentProjectChanged(new ProjectEventArgs(currentProject));
			}
		}
		
		public Combine CurrentSelectedCombine {
			get {
				return currentCombine;
			}
			set {
				System.Diagnostics.Debug.Assert(openCombine != null);
				currentCombine = value;
				OnCurrentSelectedCombineChanged(new CombineEventArgs(currentCombine));
			}
		}
		
		public Combine CurrentOpenCombine {
			get {
				return openCombine;
			}
			set {
				openCombine = value;
			}
		}
		
		bool IsDirtyFileInCombine {
			get {
				ArrayList projects = Combine.GetAllProjects(openCombine);
				
				foreach (ProjectCombineEntry projectEntry in projects) {
					foreach (ProjectFile fInfo in projectEntry.Project.ProjectFiles) {
						foreach (IViewContent content in WorkbenchSingleton.Workbench.ViewContentCollection) {
							if (content.IsDirty && content.FileName == fInfo.Name) {
								return true;
							}
						}
					}
				}
				return false;
			}
		}
		
		public bool NeedsCompiling {
			get {
				if (openCombine == null) {
					return false;
				}
				return openCombine.NeedsBuilding || IsDirtyFileInCombine;
			}
		}
		
		public void SaveCombinePreferences()
		{
			if (CurrentOpenCombine != null) {
				SaveCombinePreferences(CurrentOpenCombine, openCombineFileName);
			}
		}
		
		public void CloseCombine()
		{
			CloseCombine(true);
		}

		public void CloseCombine(bool saveCombinePreferencies)
		{
			if (CurrentOpenCombine != null) {
				if (saveCombinePreferencies)
					SaveCombinePreferences(CurrentOpenCombine, openCombineFileName);
				
				Combine closedCombine = CurrentOpenCombine;
				CurrentSelectedProject = null;
				CurrentOpenCombine = CurrentSelectedCombine = null;
				openCombineFileName = null;
				WorkbenchSingleton.Workbench.CloseAllViews();
				OnCombineClosed(new CombineEventArgs(closedCombine));
				closedCombine.Dispose();
			}
		}
		
		FileUtilityService fileUtilityService = (FileUtilityService)ServiceManager.Services.GetService(typeof(FileUtilityService));
		
		public void OpenCombine(string filename)
		{
			if (openCombine != null) {
				SaveCombine();
				CloseCombine();
			}
				
			if (!fileUtilityService.TestFileExists(filename)) {
				return;
			}
			IStatusBarService statusBarService = (IStatusBarService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(IStatusBarService));
			statusBarService.SetMessage("${res:MainWindow.StatusBar.OpeningCombineMessage}");
				
			if (Path.GetExtension(filename).ToUpper() == ".PRJX") {
				string validcombine = Path.ChangeExtension(filename, ".cmbx");
				if (File.Exists(validcombine)) {
					LoadCombine(validcombine);
				} else {
					Combine loadingCombine = new Combine();
					IProject project = (IProject)loadingCombine.AddEntry(filename);
					if (project == null) {
						return;
					}
					loadingCombine.Name = project.Name;
					loadingCombine.SaveCombine(validcombine);
					LoadCombine(validcombine);
				}
			} else {
				LoadCombine(filename);
			}
			statusBarService.SetMessage("${res:MainWindow.StatusBar.ReadyMessage}");
		}
		
		void LoadCombine(string filename)
		{
			if (!fileUtilityService.TestFileExists(filename)) {
				return;
			}
			
			Combine loadingCombine = new Combine();
			loadingCombine.LoadCombine(filename);
			openCombine         = loadingCombine;
			openCombineFileName = filename;
			
			IFileService fileService = (IFileService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(IFileService));
			fileService.RecentOpen.AddLastProject(filename);
			
			OnCombineOpened(new CombineEventArgs(openCombine));
			
			RestoreCombinePreferences(CurrentOpenCombine, openCombineFileName);
		}
		
		void Save(string fileName)
		{
			if (openCombine != null) {
				openCombineFileName = fileName;
				openCombine.SaveCombine(fileName);
				openCombine.SaveAllProjects();
			}
		}
		
		public ProjectReference GetReferenceFromProject(IProject prj, string filename)
		{
			foreach (ProjectReference rInfo in prj.ProjectReferences) {
				if (rInfo.Reference == filename) {
					return rInfo;
				}
			}
			ProjectReference newReferenceInformation = new ProjectReference(ReferenceType.Assembly, filename);
			prj.ProjectReferences.Add(newReferenceInformation);
			return newReferenceInformation;
		}
		
		public bool AddReferenceToProject(IProject prj, ProjectReference reference)
		{
			foreach (ProjectReference refproj in currentProject.ProjectReferences) {
				if (reference.Equals(refproj.Reference)) {
					return false;
				}
			}
			prj.ProjectReferences.Add(reference);
			ICSharpCode.SharpDevelop.Gui.Pads.ProjectBrowser.ProjectBrowserView pbv = (ICSharpCode.SharpDevelop.Gui.Pads.ProjectBrowser.ProjectBrowserView)WorkbenchSingleton.Workbench.GetPad(typeof(ICSharpCode.SharpDevelop.Gui.Pads.ProjectBrowser.ProjectBrowserView));
			pbv.UpdateCombineTree();
			SaveCombine();
			return true;
		}
		
		public ProjectFile AddFileToProject(IProject prj, string filename, BuildAction action)
		{
			foreach (ProjectFile fInfo in prj.ProjectFiles) {
				if (fInfo.Name == filename) {
					return fInfo;
				}
			}
			ProjectFile newFileInformation = new ProjectFile(filename, action);
			prj.ProjectFiles.Add(newFileInformation);
			return newFileInformation;
		}
		
		public void AddFileToProject(IProject prj, ProjectFile projectFile) {
			prj.ProjectFiles.Add(projectFile);
			
		}

		
		public void SaveCombine()
		{
			Save(openCombineFileName);
		}
		
		public void MarkFileDirty(string filename)
		{
			if (openCombine != null) {
				ProjectCombineEntry entry = openCombine.GetProjectEntryContaining(filename);
				if (entry != null) {
					entry.IsDirty = true;
				}
			}
		}
		
		public void MarkProjectDirty(IProject project)
		{
			if (openCombine != null) {
				ArrayList projectEntries = Combine.GetAllProjects(openCombine);
				foreach (ProjectCombineEntry entry in projectEntries) {
					if (entry.Project == project) {
						entry.IsDirty = true;
						break;
					}
				}
			}
		}
		
		public void CompileCombine()
		{
			if (openCombine != null) {
				DoBeforeCompileAction();
				TaskService taskService = (TaskService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(TaskService));
				taskService.Tasks.Clear();
				taskService.NotifyTaskChange();
				
				openCombine.Build(false);
			}
		}
		
		public void RecompileAll()
		{
			if (openCombine != null) {
				DoBeforeCompileAction();
				TaskService taskService = (TaskService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(TaskService));
				taskService.Tasks.Clear();
				taskService.NotifyTaskChange();
				
				openCombine.Build(true);
			}
		}
		
		ILanguageBinding BeforeCompile(IProject project)
		{
			DoBeforeCompileAction();
			TaskService taskService = (TaskService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(TaskService));
			StringParserService stringParserService = (StringParserService)ServiceManager.Services.GetService(typeof(StringParserService));
			
			taskService.NotifyTaskChange();
			
			// cut&pasted from CombineEntry.cs
			stringParserService.Properties["Project"] = project.Name;
			IProjectService   projectService   = (IProjectService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(IProjectService));
			IStatusBarService statusBarService = (IStatusBarService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(IStatusBarService));
			IResourceService resourceService   = (IResourceService)ServiceManager.Services.GetService(typeof(IResourceService));
			
			statusBarService.SetMessage("${res:MainWindow.StatusBar.CompilingMessage}");
			LanguageBindingService languageBindingService = (LanguageBindingService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(LanguageBindingService));
			
			// create output directory, if not exists
			string outputDir = ((AbstractProjectConfiguration)project.ActiveConfiguration).OutputDirectory;
			try {
				DirectoryInfo directoryInfo = new DirectoryInfo(outputDir);
				if (!directoryInfo.Exists) {
					directoryInfo.Create();
				}
			} catch (Exception e) {
				throw new ApplicationException("Can't create project output directory " + outputDir + " original exception:\n" + e.ToString());
			}
			
			AbstractProjectConfiguration conf = project.ActiveConfiguration as AbstractProjectConfiguration;
			taskService.CompilerOutput += stringParserService.Parse("${res:MainWindow.CompilerMessages.BuildStartedOutput}", new string[,] { {"PROJECT", project.Name}, {"CONFIG", project.ActiveConfiguration.Name} }) + "\n";
			taskService.CompilerOutput += resourceService.GetString("MainWindow.CompilerMessages.PerformingMainCompilationOutput") + "\n";
			
			if (conf != null && conf.ExecuteBeforeBuild != null && conf.ExecuteBeforeBuild.Length > 0) {
				string command   = conf.ExecuteBeforeBuild;
				string arguments = conf.ExecuteBeforeBuildArguments;
				
				if (File.Exists(command)) {
					taskService.CompilerOutput += stringParserService.Parse("${res:MainWindow.CompilerMessages.ExecuteScript}", new string[,] { {"SCRIPT", conf.ExecuteBeforeBuild} }) + "\n";
					ProcessStartInfo ps = new ProcessStartInfo(command, arguments);
					ps.UseShellExecute = false;
					ps.RedirectStandardOutput = true;
					ps.WorkingDirectory = Path.GetDirectoryName(command);
					Process process = new Process();
					process.StartInfo = ps;
					process.Start();
					taskService.CompilerOutput += process.StandardOutput.ReadToEnd();
				}
			}
			
			ILanguageBinding binding = languageBindingService.GetBindingPerLanguageName(project.ProjectType);
			
			// cut&paste END
			return binding;
		}
		
		void AfterCompile(IProject project, ICompilerResult res)
		{
			// cut&pasted from CombineEntry.cs
			TaskService taskService = (TaskService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(TaskService));
			foreach (CompilerError err in res.CompilerResults.Errors) {
				taskService.Tasks.Add(new Task(project, err));
			}
			StringParserService stringParserService = (StringParserService)ServiceManager.Services.GetService(typeof(StringParserService));
			
			AbstractProjectConfiguration conf = project.ActiveConfiguration as AbstractProjectConfiguration;
			
			if (conf != null && taskService.Errors == 0 && conf.ExecuteAfterBuild != null && conf.ExecuteAfterBuild.Length > 0) {
				taskService.CompilerOutput += stringParserService.Parse("${res:MainWindow.CompilerMessages.ExecuteScript}", new string[,] { {"SCRIPT", conf.ExecuteAfterBuild} }) + "\n";
				string command   = conf.ExecuteAfterBuild;
				string arguments = conf.ExecuteAfterBuildArguments;
				
				if (File.Exists(command)) {
					ProcessStartInfo ps = new ProcessStartInfo(command, arguments);
					ps.UseShellExecute = false;
					ps.RedirectStandardOutput = true;
					ps.WorkingDirectory = Path.GetDirectoryName(command);
					Process process = new Process();
					process.StartInfo = ps;
					process.Start();
					taskService.CompilerOutput += process.StandardOutput.ReadToEnd();
				}
			}
			taskService.NotifyTaskChange();
			taskService.CompilerOutput += res.CompilerOutput + stringParserService.Parse("${res:MainWindow.CompilerMessages.ProjectStatsOutput}", new string[,] { {"ERRORS", taskService.Errors.ToString()}, {"WARNINGS", taskService.Warnings.ToString()} }) + "\n\n";
		
		}
		
		public ICompilerResult RecompileProject(IProject project)
		{
			ICompilerResult res = BeforeCompile(project).RecompileProject(project);
			AfterCompile(project, res);
			return res;
		}
		
		public ICompilerResult CompileProject(IProject project)
		{
			ICompilerResult res = BeforeCompile(project).CompileProject(project);
			AfterCompile(project, res);
			return res;
		}
		
		void DoBeforeCompileAction()
		{
			PropertyService propertyService = (PropertyService)ServiceManager.Services.GetService(typeof(PropertyService));
			BeforeCompileAction action = (BeforeCompileAction)propertyService.GetProperty("SharpDevelop.Services.DefaultParserService.BeforeCompileAction", BeforeCompileAction.SaveAllFiles);
			
			switch (action) {
				case BeforeCompileAction.Nothing:
					break;
				case BeforeCompileAction.PromptForSave:
					bool save = false;
					foreach (IViewContent content in WorkbenchSingleton.Workbench.ViewContentCollection) {
						if (content.FileName != null && content.IsDirty) {
							if (!save) {
								IMessageService messageService =(IMessageService)ServiceManager.Services.GetService(typeof(IMessageService));
								if (messageService.AskQuestion("${res:MainWindow.SaveChangesMessage}")) {
									save = true;
								} else {
									break;
								}
							}
							MarkFileDirty(content.FileName);
							content.Save();
						}
					}
					break;
				case BeforeCompileAction.SaveAllFiles:
					foreach (IViewContent content in WorkbenchSingleton.Workbench.ViewContentCollection) {
						if (content.FileName != null && content.IsDirty) {
							MarkFileDirty(content.FileName);
							content.Save();
						}
					}
					break;
				default:
					System.Diagnostics.Debug.Assert(false);
					break;
			}
		}
		
		public ProjectFile RetrieveFileInformationForFile(string fileName)
		{
			ArrayList projects = Combine.GetAllProjects(openCombine);
			
			foreach (ProjectCombineEntry projectEntry in projects) {
				foreach (ProjectFile fInfo in projectEntry.Project.ProjectFiles) {
					if (fInfo.Name == fileName) {
						return fInfo;
					}
				}
			}
			return null;
		}
		
		void RemoveFileFromAllProjects(string fileName)
		{
			ArrayList projects = Combine.GetAllProjects(openCombine);
			

⌨️ 快捷键说明

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