30 changed files with 1243 additions and 1012 deletions
@ -0,0 +1,276 @@
@@ -0,0 +1,276 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Diagnostics; |
||||
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Debugging; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.AspNet.Mvc |
||||
{ |
||||
public class WebBehavior : ProjectBehavior |
||||
{ |
||||
ProcessMonitor monitor; |
||||
|
||||
public WebBehavior(MSBuildBasedProject project, ProjectBehavior next = null) |
||||
: base(project, next) |
||||
{ |
||||
|
||||
} |
||||
|
||||
new MSBuildBasedProject Project { |
||||
get { |
||||
return (MSBuildBasedProject)base.Project; |
||||
} |
||||
} |
||||
|
||||
public string StartProgram { |
||||
get { |
||||
return ((MSBuildBasedProject)Project).GetEvaluatedProperty("StartProgram") ?? ""; |
||||
} |
||||
set { |
||||
((MSBuildBasedProject)Project).SetProperty("StartProgram", string.IsNullOrEmpty(value) ? null : value); |
||||
} |
||||
} |
||||
|
||||
public string StartUrl { |
||||
get { |
||||
return ((MSBuildBasedProject)Project).GetEvaluatedProperty("StartURL") ?? ""; |
||||
} |
||||
set { |
||||
((MSBuildBasedProject)Project).SetProperty("StartURL", string.IsNullOrEmpty(value) ? null : value); |
||||
} |
||||
} |
||||
|
||||
public const string LocalHost = "http://localhost"; |
||||
|
||||
public override bool IsStartable { |
||||
get { return true; } |
||||
} |
||||
|
||||
public override ProcessStartInfo CreateStartInfo() |
||||
{ |
||||
return new ProcessStartInfo(LocalHost); |
||||
} |
||||
|
||||
// TODO horrible CODE DUPLICATION
|
||||
public override void Start(bool withDebugging) |
||||
{ |
||||
var processStartInfo = CreateStartInfo(); |
||||
if (FileUtility.IsUrl(processStartInfo.FileName)) { |
||||
if (!CheckWebProjectStartInfo()) |
||||
return; |
||||
// we deal with a WebProject
|
||||
try { |
||||
var project = ProjectService.OpenSolution.StartupProject as CompilableProject; |
||||
WebProjectOptions options = WebProjectsOptions.Instance.GetWebProjectOptions(project.Name); |
||||
System.Diagnostics.Process defaultAppProcess = null; |
||||
|
||||
string processName = WebProjectService.GetWorkerProcessName(options.Data.WebServer); |
||||
|
||||
// try find the worker process directly or using the process monitor callback
|
||||
var processes = System.Diagnostics.Process.GetProcesses(); |
||||
int index = processes.FindIndex(p => p.ProcessName.Equals(processName, StringComparison.OrdinalIgnoreCase)); |
||||
if (index > -1){ |
||||
DebuggerService.CurrentDebugger.Attach(processes[index]); |
||||
} else { |
||||
this.monitor = new ProcessMonitor(processName); |
||||
this.monitor.ProcessCreated += delegate { |
||||
WorkbenchSingleton.SafeThreadCall((Action)(() => OnProcessCreated(defaultAppProcess, options))); |
||||
}; |
||||
this.monitor.Start(); |
||||
|
||||
if (options.Data.WebServer == WebServer.IISExpress) { |
||||
// start IIS express and attach to it
|
||||
if (WebProjectService.IsIISExpressInstalled) { |
||||
System.Diagnostics.Process.Start(WebProjectService.IISExpressProcessLocation); |
||||
} else { |
||||
DisposeProcessMonitor(); |
||||
MessageService.ShowError("${res:ICSharpCode.WepProjectOptionsPanel.NoProjectUrlOrProgramAction}"); |
||||
return; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// start default application(e.g. browser) or the one specified
|
||||
switch (project.StartAction) { |
||||
case StartAction.Project: |
||||
if (FileUtility.IsUrl(options.Data.ProjectUrl)) { |
||||
defaultAppProcess = System.Diagnostics.Process.Start(options.Data.ProjectUrl); |
||||
} else { |
||||
MessageService.ShowError("${res:ICSharpCode.WepProjectOptionsPanel.NoProjectUrlOrProgramAction}"); |
||||
DisposeProcessMonitor(); |
||||
return; |
||||
} |
||||
break; |
||||
case StartAction.Program: |
||||
defaultAppProcess = System.Diagnostics.Process.Start(StartProgram); |
||||
break; |
||||
case StartAction.StartURL: |
||||
if (FileUtility.IsUrl(StartUrl)) |
||||
defaultAppProcess = System.Diagnostics.Process.Start(StartUrl); |
||||
else { |
||||
string url = string.Concat(options.Data.ProjectUrl, StartUrl); |
||||
if (FileUtility.IsUrl(url)) { |
||||
defaultAppProcess = System.Diagnostics.Process.Start(url); |
||||
} else { |
||||
MessageService.ShowError("${res:ICSharpCode.WepProjectOptionsPanel.NoProjectUrlOrProgramAction}"); |
||||
DisposeProcessMonitor(); |
||||
return; |
||||
} |
||||
} |
||||
break; |
||||
default: |
||||
throw new System.Exception("Invalid value for StartAction"); |
||||
} |
||||
} catch (System.Exception ex) { |
||||
string err = "Error: " + ex.Message; |
||||
MessageService.ShowError(err); |
||||
LoggingService.Error(err); |
||||
DisposeProcessMonitor(); |
||||
return; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void WithoutDebugger() |
||||
{ |
||||
var processStartInfo = CreateStartInfo(); |
||||
if (FileUtility.IsUrl(processStartInfo.FileName)) { |
||||
if (!CheckWebProjectStartInfo()) |
||||
return; |
||||
// we deal with a WebProject
|
||||
try { |
||||
var project = ProjectService.OpenSolution.StartupProject as CompilableProject; |
||||
WebProjectOptions options = WebProjectsOptions.Instance.GetWebProjectOptions(project.Name); |
||||
|
||||
string processName = WebProjectService.GetWorkerProcessName(options.Data.WebServer); |
||||
|
||||
if (options.Data.WebServer == WebServer.IISExpress) { |
||||
// start IIS express
|
||||
if (WebProjectService.IsIISExpressInstalled) |
||||
System.Diagnostics.Process.Start(WebProjectService.IISExpressProcessLocation); |
||||
else { |
||||
MessageService.ShowError("${res:ICSharpCode.WepProjectOptionsPanel.NoProjectUrlOrProgramAction}"); |
||||
return; |
||||
} |
||||
} |
||||
|
||||
// start default application(e.g. browser) or the one specified
|
||||
switch (project.StartAction) { |
||||
case StartAction.Project: |
||||
if (FileUtility.IsUrl(options.Data.ProjectUrl)) { |
||||
System.Diagnostics.Process.Start(options.Data.ProjectUrl); |
||||
} else { |
||||
MessageService.ShowError("${res:ICSharpCode.WepProjectOptionsPanel.NoProjectUrlOrProgramAction}"); |
||||
return; |
||||
} |
||||
break; |
||||
case StartAction.Program: |
||||
System.Diagnostics.Process.Start(StartProgram); |
||||
break; |
||||
case StartAction.StartURL: |
||||
if (FileUtility.IsUrl(StartUrl)) |
||||
System.Diagnostics.Process.Start(StartUrl); |
||||
else { |
||||
string url = string.Concat(options.Data.ProjectUrl, StartUrl); |
||||
if (FileUtility.IsUrl(url)) { |
||||
System.Diagnostics.Process.Start(url); |
||||
} else { |
||||
MessageService.ShowError("${res:ICSharpCode.WepProjectOptionsPanel.NoProjectUrlOrProgramAction}"); |
||||
return; |
||||
} |
||||
} |
||||
break; |
||||
default: |
||||
throw new System.Exception("Invalid value for StartAction"); |
||||
} |
||||
} catch (System.Exception ex) { |
||||
string err = "Error: " + ex.Message; |
||||
MessageService.ShowError(err); |
||||
LoggingService.Error(err); |
||||
return; |
||||
} |
||||
} |
||||
} |
||||
|
||||
bool CheckWebProjectStartInfo() |
||||
{ |
||||
// check if we have startup project
|
||||
var project = ProjectService.OpenSolution.StartupProject as CompilableProject; |
||||
if (project == null) { |
||||
MessageService.ShowError("${res:ICSharpCode.NoStartupProject}"); |
||||
return false; |
||||
} |
||||
|
||||
// check if we have options
|
||||
if (WebProjectsOptions.Instance == null) { |
||||
MessageService.ShowError("${res:ICSharpCode.WepProjectOptionsPanel.NoProjectUrlOrProgramAction}"); |
||||
return false; |
||||
} |
||||
|
||||
// check the options
|
||||
var options = WebProjectsOptions.Instance.GetWebProjectOptions(project.Name); |
||||
if (options == null || options.Data == null || string.IsNullOrEmpty(options.ProjectName) || |
||||
options.Data.WebServer == WebServer.None) { |
||||
MessageService.ShowError("${res:ICSharpCode.WepProjectOptionsPanel.NoProjectUrlOrProgramAction}"); |
||||
return false; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
void OnProcessCreated(System.Diagnostics.Process defaultAppProcess, WebProjectOptions options) |
||||
{ |
||||
string processName = WebProjectService.GetWorkerProcessName(options.Data.WebServer); |
||||
var processes = System.Diagnostics.Process.GetProcesses(); |
||||
int index = processes.FindIndex(p => p.ProcessName.Equals(processName, StringComparison.OrdinalIgnoreCase)); |
||||
if (index == -1) |
||||
return; |
||||
DebuggerService.CurrentDebugger.Attach(processes[index]); |
||||
|
||||
if (!DebuggerService.CurrentDebugger.IsAttached) { |
||||
if(options.Data.WebServer == WebServer.IIS) { |
||||
string format = ResourceService.GetString("ICSharpCode.WepProjectOptionsPanel.NoIISWP"); |
||||
MessageService.ShowMessage(string.Format(format, processName)); |
||||
} else { |
||||
DebuggerService.CurrentDebugger.Attach(defaultAppProcess); |
||||
if (!DebuggerService.CurrentDebugger.IsAttached) { |
||||
MessageService.ShowMessage(ResourceService.GetString("ICSharpCode.WepProjectOptionsPanel.UnableToAttach")); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
void DisposeProcessMonitor() |
||||
{ |
||||
if (monitor != null) { |
||||
monitor.Stop(); |
||||
monitor.Dispose(); |
||||
monitor = null; |
||||
} |
||||
} |
||||
|
||||
public override ICSharpCode.Core.Properties CreateMemento() |
||||
{ |
||||
var properties = base.CreateMemento(); |
||||
// web project properties
|
||||
var webOptions = WebProjectsOptions.Instance.GetWebProjectOptions(Project.Name); |
||||
if (webOptions != null) |
||||
properties.Set("WebProjectOptions", webOptions); |
||||
return properties; |
||||
} |
||||
|
||||
public override void SetMemento(ICSharpCode.Core.Properties memento) |
||||
{ |
||||
// web project properties
|
||||
WebProjectsOptions.Instance.SetWebProjectOptions(Project.Name, memento.Get("WebProjectOptions", new WebProjectOptions()) as WebProjectOptions); |
||||
base.SetMemento(memento); |
||||
} |
||||
} |
||||
} |
@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<UserControl |
||||
x:Class="ICSharpCode.SharpDevelop.Gui.OptionPanels.WebProjectOptionsPanel" |
||||
x:Class="ICSharpCode.AspNet.Mvc.WebProjectOptionsPanel" |
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
xmlns:core="http://icsharpcode.net/sharpdevelop/core" |
||||
xmlns:widgets="http://icsharpcode.net/sharpdevelop/widgets" |
@ -1,123 +0,0 @@
@@ -1,123 +0,0 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Windows; |
||||
using System.Windows.Forms; |
||||
using System.Windows.Forms.Integration; |
||||
using System.Windows.Media; |
||||
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using RadioBinding = System.Collections.Generic.KeyValuePair<ICSharpCode.SharpDevelop.Project.StartAction, System.Windows.Forms.RadioButton>; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Gui.OptionPanels |
||||
{ |
||||
public class aaDebugOptions : AbstractXmlFormsProjectOptionPanel |
||||
{ |
||||
public override void LoadPanelContents() |
||||
{ |
||||
SetupFromXmlResource("ProjectOptions.DebugOptions.xfrm"); |
||||
ConnectBrowseButton("startExternalProgramBrowseButton", "startExternalProgramTextBox", |
||||
"${res:SharpDevelop.FileFilter.ExecutableFiles}|*.exe;*.com;*.pif;*.bat;*.cmd", |
||||
TextBoxEditMode.EditRawProperty); |
||||
ConnectBrowseFolder("workingDirectoryBrowseButton", "workingDirectoryTextBox", |
||||
TextBoxEditMode.EditRawProperty); |
||||
|
||||
InitializeHelper(); |
||||
|
||||
ConfigurationGuiBinding b; |
||||
ChooseStorageLocationButton locationButton; |
||||
|
||||
b = helper.BindRadioEnum("StartAction", |
||||
new RadioBinding(StartAction.Project, Get<RadioButton>("startProject")), |
||||
new RadioBinding(StartAction.Program, Get<RadioButton>("startExternalProgram")), |
||||
new RadioBinding(StartAction.StartURL, Get<RadioButton>("startBrowserInURL"))); |
||||
b.DefaultLocation = PropertyStorageLocations.ConfigurationSpecific; |
||||
locationButton = b.CreateLocationButtonInPanel("startActionGroupBox"); |
||||
|
||||
b = helper.BindString("startExternalProgramTextBox", "StartProgram", TextBoxEditMode.EditRawProperty); |
||||
b.DefaultLocation = PropertyStorageLocations.ConfigurationSpecific; |
||||
b.RegisterLocationButton(locationButton); |
||||
|
||||
b = helper.BindString("startBrowserInURLTextBox", "StartURL", TextBoxEditMode.EditRawProperty); |
||||
b.DefaultLocation = PropertyStorageLocations.ConfigurationSpecific; |
||||
b.RegisterLocationButton(locationButton); |
||||
|
||||
Get<RadioButton>("startExternalProgram").CheckedChanged += UpdateEnabledStates; |
||||
Get<RadioButton>("startBrowserInURL").CheckedChanged += UpdateEnabledStates; |
||||
|
||||
b = helper.BindString("commandLineArgumentsTextBox", "StartArguments", TextBoxEditMode.EditRawProperty); |
||||
locationButton = b.CreateLocationButtonInPanel("startOptionsGroupBox"); |
||||
b = helper.BindString("workingDirectoryTextBox", "StartWorkingDirectory", TextBoxEditMode.EditRawProperty); |
||||
b.RegisterLocationButton(locationButton); |
||||
|
||||
UpdateEnabledStates(this, EventArgs.Empty); |
||||
|
||||
helper.AddConfigurationSelector(this); |
||||
|
||||
// add server for web projects
|
||||
if (ProjectService.CurrentProject is CompilableProject) { |
||||
bool isWebProject = ((CompilableProject)ProjectService.CurrentProject).IsWebProject; |
||||
if (isWebProject) { |
||||
GroupBox winFormsGroupBox = new GroupBox(); |
||||
|
||||
winFormsGroupBox.Text = ResourceService.GetString("ICSharpCode.WepProjectOptionsPanel.Server"); |
||||
winFormsGroupBox.Location = new System.Drawing.Point(8,240); |
||||
winFormsGroupBox.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right; |
||||
winFormsGroupBox.Size = new System.Drawing.Size(460,200); |
||||
|
||||
Controls.Add(winFormsGroupBox); |
||||
|
||||
ElementHost host = new ElementHost(); |
||||
host.Top = 30; |
||||
host.Left = 10; |
||||
host.AutoSize = true; |
||||
host.Child = new WebProjectOptionsPanel(this); |
||||
winFormsGroupBox.Controls.Add(host); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
public override bool StorePanelContents() |
||||
{ |
||||
// SaveWpfSettings();
|
||||
return base.StorePanelContents(); |
||||
} |
||||
|
||||
|
||||
void UpdateEnabledStates(object sender, EventArgs e) |
||||
{ |
||||
Get<TextBox>("startExternalProgram").Enabled = Get<Button>("startExternalProgramBrowse").Enabled = Get<RadioButton>("startExternalProgram").Checked; |
||||
Get<TextBox>("startBrowserInURL").Enabled = Get<RadioButton>("startBrowserInURL").Checked; |
||||
} |
||||
|
||||
public void SetStartAction(StartAction action) |
||||
{ |
||||
switch(action) { |
||||
case StartAction.Project: |
||||
Get<RadioButton>("startProject").Checked = true; |
||||
break; |
||||
case StartAction.Program: |
||||
Get<RadioButton>("startExternalProgram").Checked = true; |
||||
break; |
||||
case StartAction.StartURL: |
||||
Get<RadioButton>("startBrowserInURL").Checked = true; |
||||
break; |
||||
default: |
||||
throw new NotSupportedException("Unknown action!"); |
||||
} |
||||
|
||||
UpdateEnabledStates(null, EventArgs.Empty); |
||||
} |
||||
|
||||
public void SetExternalProgram(string externalProgram) |
||||
{ |
||||
if (externalProgram == null) |
||||
return; |
||||
|
||||
Get<TextBox>("startExternalProgram").Text = externalProgram; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,125 @@
@@ -0,0 +1,125 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Diagnostics; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using System.Xml.Linq; |
||||
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Debugging; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Gui.OptionPanels; |
||||
using ICSharpCode.SharpDevelop.Project.Converter; |
||||
using ICSharpCode.SharpDevelop.Util; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Project |
||||
{ |
||||
public sealed class DefaultProjectBehavior : ProjectBehavior |
||||
{ |
||||
public DefaultProjectBehavior(AbstractProject project) |
||||
: base(project) |
||||
{ |
||||
} |
||||
|
||||
new AbstractProject Project { |
||||
get { |
||||
return (AbstractProject)base.Project; |
||||
} |
||||
} |
||||
|
||||
public override bool IsStartable { |
||||
get { return false; } |
||||
} |
||||
|
||||
public override void Start(bool withDebugging) |
||||
{ |
||||
ProcessStartInfo psi; |
||||
try { |
||||
psi = CreateStartInfo(); |
||||
} catch (ProjectStartException ex) { |
||||
MessageService.ShowError(ex.Message); |
||||
return; |
||||
} |
||||
if (withDebugging) { |
||||
DebuggerService.CurrentDebugger.Start(psi); |
||||
} else { |
||||
DebuggerService.CurrentDebugger.StartWithoutDebugging(psi); |
||||
} |
||||
} |
||||
|
||||
public override ProcessStartInfo CreateStartInfo() |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
|
||||
public override ItemType GetDefaultItemType(string fileName) |
||||
{ |
||||
return ItemType.None; |
||||
} |
||||
|
||||
public override ProjectItem CreateProjectItem(IProjectItemBackendStore item) |
||||
{ |
||||
return new UnknownProjectItem(Project, item); |
||||
} |
||||
|
||||
public override void ProjectCreationComplete() |
||||
{ |
||||
|
||||
} |
||||
|
||||
public override IEnumerable<CompilerVersion> GetAvailableCompilerVersions() |
||||
{ |
||||
yield break; |
||||
} |
||||
|
||||
public override void UpgradeProject(CompilerVersion newVersion, TargetFramework newFramework) |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
|
||||
|
||||
/// <summary>
|
||||
/// Saves project preferences (currently opened files, bookmarks etc.) to the
|
||||
/// a property container.
|
||||
/// </summary>
|
||||
public override Properties CreateMemento() |
||||
{ |
||||
WorkbenchSingleton.AssertMainThread(); |
||||
|
||||
// breakpoints and files
|
||||
Properties properties = new Properties(); |
||||
properties.Set("bookmarks", ICSharpCode.SharpDevelop.Bookmarks.BookmarkManager.GetProjectBookmarks(Project).ToArray()); |
||||
List<string> files = new List<string>(); |
||||
foreach (string fileName in FileService.GetOpenFiles()) { |
||||
if (fileName != null && Project.IsFileInProject(fileName)) { |
||||
files.Add(fileName); |
||||
} |
||||
} |
||||
properties.Set("files", files.ToArray()); |
||||
|
||||
// other project data
|
||||
properties.Set("projectSavedData", Project.ProjectSpecificProperties ?? new Properties()); |
||||
|
||||
return properties; |
||||
} |
||||
|
||||
public override void SetMemento(Properties memento) |
||||
{ |
||||
WorkbenchSingleton.AssertMainThread(); |
||||
|
||||
foreach (ICSharpCode.SharpDevelop.Bookmarks.SDBookmark mark in memento.Get("bookmarks", new ICSharpCode.SharpDevelop.Bookmarks.SDBookmark[0])) { |
||||
ICSharpCode.SharpDevelop.Bookmarks.BookmarkManager.AddMark(mark); |
||||
} |
||||
foreach (string fileName in memento.Get("files", new string[0])) { |
||||
AbstractProject.filesToOpenAfterSolutionLoad.Add(fileName); |
||||
} |
||||
|
||||
// other project data
|
||||
Project.ProjectSpecificProperties = memento.Get("projectSavedData", new Properties()); |
||||
base.SetMemento(memento); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,363 @@
@@ -0,0 +1,363 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Diagnostics; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using System.Xml.Linq; |
||||
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Debugging; |
||||
using ICSharpCode.SharpDevelop.Gui.OptionPanels; |
||||
using ICSharpCode.SharpDevelop.Project.Converter; |
||||
using ICSharpCode.SharpDevelop.Util; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Project |
||||
{ |
||||
public class DotNetStartBehavior : ProjectBehavior |
||||
{ |
||||
static string RemoveQuotes(string text) |
||||
{ |
||||
if (text.StartsWith("\"") && text.EndsWith("\"")) |
||||
return text.Substring(1, text.Length - 2); |
||||
else |
||||
return text; |
||||
} |
||||
|
||||
public DotNetStartBehavior(CompilableProject project, ProjectBehavior next = null) |
||||
: base(project, next) |
||||
{ |
||||
|
||||
} |
||||
|
||||
public override bool IsStartable { |
||||
get { |
||||
switch (StartAction) { |
||||
case StartAction.Project: |
||||
return ((CompilableProject)Project).OutputType == OutputType.Exe || ((CompilableProject)Project).OutputType == OutputType.WinExe; |
||||
case StartAction.Program: |
||||
return StartProgram.Length > 0; |
||||
case StartAction.StartURL: |
||||
return StartUrl.Length > 0; |
||||
default: |
||||
return base.IsStartable; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public override ProcessStartInfo CreateStartInfo() |
||||
{ |
||||
switch (StartAction) { |
||||
case StartAction.Project: |
||||
return CreateStartInfo(Project.OutputAssemblyFullPath, Project.Directory, StartWorkingDirectory, StartArguments); |
||||
case StartAction.Program: |
||||
return CreateStartInfo(StartProgram, Project.Directory, StartWorkingDirectory, StartArguments); |
||||
case StartAction.StartURL: |
||||
string url = StartUrl; |
||||
if (!FileUtility.IsUrl(url)) |
||||
url = "http://" + url; |
||||
return new ProcessStartInfo(url); |
||||
default: |
||||
return base.CreateStartInfo(); |
||||
} |
||||
} |
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="ProcessStartInfo"/> for the specified program, using
|
||||
/// arguments and working directory from the project options.
|
||||
/// </summary>
|
||||
public static ProcessStartInfo CreateStartInfo(string program, string projectDirectory, string startWorkingDirectory, string startArguments) |
||||
{ |
||||
program = RemoveQuotes(program); |
||||
if (!FileUtility.IsValidPath(program)) { |
||||
throw new ProjectStartException(program + " is not a valid path; the process cannot be started."); |
||||
} |
||||
ProcessStartInfo psi = new ProcessStartInfo(); |
||||
psi.FileName = Path.Combine(projectDirectory, program); |
||||
string workingDir = StringParser.Parse(startWorkingDirectory); |
||||
|
||||
if (workingDir.Length == 0) { |
||||
psi.WorkingDirectory = Path.GetDirectoryName(psi.FileName); |
||||
} else { |
||||
workingDir = RemoveQuotes(workingDir); |
||||
|
||||
if (!FileUtility.IsValidPath(workingDir)) { |
||||
throw new ProjectStartException("Working directory '" + workingDir + "' is invalid; the process cannot be started. You can specify the working directory in the project options."); |
||||
} |
||||
psi.WorkingDirectory = Path.Combine(projectDirectory, workingDir); |
||||
} |
||||
psi.Arguments = StringParser.Parse(startArguments); |
||||
|
||||
if (!File.Exists(psi.FileName)) { |
||||
throw new ProjectStartException(psi.FileName + " does not exist and cannot be started."); |
||||
} |
||||
if (!System.IO.Directory.Exists(psi.WorkingDirectory)) { |
||||
throw new ProjectStartException("Working directory " + psi.WorkingDirectory + " does not exist; the process cannot be started. You can specify the working directory in the project options."); |
||||
} |
||||
return psi; |
||||
} |
||||
|
||||
public override void ProjectCreationComplete() |
||||
{ |
||||
TargetFramework fx = ((CompilableProject)Project).CurrentTargetFramework; |
||||
if (fx != null && (fx.IsBasedOn(TargetFramework.Net35) || fx.IsBasedOn(TargetFramework.Net35Client))) { |
||||
AddDotnet35References(); |
||||
} |
||||
if (fx != null && (fx.IsBasedOn(TargetFramework.Net40) || fx.IsBasedOn(TargetFramework.Net40Client))) { |
||||
AddDotnet40References(); |
||||
} |
||||
if (fx != null) |
||||
UpdateAppConfig(fx); |
||||
base.ProjectCreationComplete(); |
||||
} |
||||
|
||||
public override ItemType GetDefaultItemType(string fileName) |
||||
{ |
||||
string extension = Path.GetExtension(fileName); |
||||
if (".resx".Equals(extension, StringComparison.OrdinalIgnoreCase) |
||||
|| ".resources".Equals(extension, StringComparison.OrdinalIgnoreCase)) |
||||
return ItemType.EmbeddedResource; |
||||
|
||||
return base.GetDefaultItemType(fileName); |
||||
} |
||||
|
||||
public override IEnumerable<CompilerVersion> GetAvailableCompilerVersions() |
||||
{ |
||||
return new[] { CompilerVersion.MSBuild20, CompilerVersion.MSBuild35, CompilerVersion.MSBuild40 }; |
||||
} |
||||
|
||||
public override void UpgradeProject(CompilerVersion newVersion, TargetFramework newFramework) |
||||
{ |
||||
if (!Project.ReadOnly) { |
||||
lock (Project.SyncRoot) { |
||||
TargetFramework oldFramework = ((CompilableProject)Project).CurrentTargetFramework; |
||||
if (newVersion != null && GetAvailableCompilerVersions().Contains(newVersion)) { |
||||
((CompilableProject)Project).SetToolsVersion(newVersion.MSBuildVersion.Major + "." + newVersion.MSBuildVersion.Minor); |
||||
} |
||||
if (newFramework != null) { |
||||
UpdateAppConfig(newFramework); |
||||
|
||||
ClientProfileTargetFramework clientProfile = newFramework as ClientProfileTargetFramework; |
||||
if (clientProfile != null) { |
||||
newFramework = clientProfile.FullFramework; |
||||
((MSBuildBasedProject)Project).SetProperty(null, null, "TargetFrameworkProfile", "Client", PropertyStorageLocations.Base, true); |
||||
} else { |
||||
((MSBuildBasedProject)Project).SetProperty(null, null, "TargetFrameworkProfile", "", PropertyStorageLocations.Base, true); |
||||
} |
||||
((MSBuildBasedProject)Project).SetProperty(null, null, "TargetFrameworkVersion", newFramework.Name, PropertyStorageLocations.Base, true); |
||||
|
||||
if (oldFramework is ClientProfileTargetFramework) |
||||
oldFramework = ((ClientProfileTargetFramework)oldFramework).FullFramework; |
||||
|
||||
if (oldFramework != null && !oldFramework.IsBasedOn(TargetFramework.Net35) && newFramework.IsBasedOn(TargetFramework.Net35)) |
||||
AddDotnet35References(); |
||||
else if (oldFramework != null && oldFramework.IsBasedOn(TargetFramework.Net35) && !newFramework.IsBasedOn(TargetFramework.Net35)) |
||||
RemoveDotnet35References(); |
||||
|
||||
if (oldFramework != null && !oldFramework.IsBasedOn(TargetFramework.Net40) && newFramework.IsBasedOn(TargetFramework.Net40)) |
||||
AddDotnet40References(); |
||||
else if (oldFramework != null && oldFramework.IsBasedOn(TargetFramework.Net40) && !newFramework.IsBasedOn(TargetFramework.Net40)) |
||||
RemoveDotnet40References(); |
||||
} |
||||
AddOrRemoveExtensions(); |
||||
Project.Save(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void AddDotnet35References() |
||||
{ |
||||
AddReferenceIfNotExists("System.Core", "3.5"); |
||||
|
||||
if (Project.GetItemsOfType(ItemType.Reference).Any(r => string.Equals(r.Include, "System.Data", StringComparison.OrdinalIgnoreCase))) { |
||||
AddReferenceIfNotExists("System.Data.DataSetExtensions", "3.5"); |
||||
} |
||||
if (Project.GetItemsOfType(ItemType.Reference).Any(r => string.Equals(r.Include, "System.Xml", StringComparison.OrdinalIgnoreCase))) { |
||||
AddReferenceIfNotExists("System.Xml.Linq", "3.5"); |
||||
} |
||||
} |
||||
|
||||
void RemoveDotnet35References() |
||||
{ |
||||
// undo "AddDotnet35References"
|
||||
RemoveReference("System.Core"); |
||||
RemoveReference("System.Data.DataSetExtensions"); |
||||
RemoveReference("System.Xml.Linq"); |
||||
} |
||||
|
||||
void AddDotnet40References() |
||||
{ |
||||
if (Project.GetItemsOfType(ItemType.Reference).Any(r => string.Equals(r.Include, "WindowsBase", StringComparison.OrdinalIgnoreCase))) { |
||||
AddReferenceIfNotExists("System.Xaml", "4.0"); |
||||
} |
||||
} |
||||
|
||||
protected virtual void RemoveDotnet40References() |
||||
{ |
||||
RemoveReference("System.Xaml"); |
||||
} |
||||
|
||||
void AddReferenceIfNotExists(string name, string requiredTargetFramework) |
||||
{ |
||||
if (!(Project.GetItemsOfType(ItemType.Reference).Any(r => string.Equals(r.Include, name, StringComparison.OrdinalIgnoreCase)))) { |
||||
ReferenceProjectItem rpi = new ReferenceProjectItem(Project, name); |
||||
if (requiredTargetFramework != null) |
||||
rpi.SetMetadata("RequiredTargetFramework", requiredTargetFramework); |
||||
ProjectService.AddProjectItem(Project, rpi); |
||||
} |
||||
} |
||||
|
||||
void RemoveReference(string name) |
||||
{ |
||||
ProjectItem reference = Project.GetItemsOfType(ItemType.Reference).FirstOrDefault(r => string.Equals(r.Include, name, StringComparison.OrdinalIgnoreCase)); |
||||
if (reference != null) |
||||
ProjectService.RemoveProjectItem(Project, reference); |
||||
} |
||||
|
||||
void UpdateAppConfig(TargetFramework newFramework) |
||||
{ |
||||
// When changing the target framework, update any existing app.config
|
||||
// Also, for applications (not libraries), create an app.config is it is required for the target framework
|
||||
bool createAppConfig = newFramework.RequiresAppConfigEntry && (((CompilableProject)Project).OutputType != OutputType.Library && ((CompilableProject)Project).OutputType != OutputType.Module); |
||||
|
||||
string appConfigFileName = CompilableProject.GetAppConfigFile(Project, createAppConfig); |
||||
if (appConfigFileName == null) |
||||
return; |
||||
|
||||
using (FakeXmlViewContent xml = new FakeXmlViewContent(appConfigFileName)) { |
||||
if (xml.Document != null) { |
||||
XElement configuration = xml.Document.Root; |
||||
XElement startup = configuration.Element("startup"); |
||||
if (startup == null) { |
||||
startup = new XElement("startup"); |
||||
if (configuration.HasElements && configuration.Elements().First().Name == "configSections") { |
||||
// <configSections> must be first element
|
||||
configuration.Elements().First().AddAfterSelf(startup); |
||||
} else { |
||||
startup = configuration.AddFirstWithIndentation(startup); |
||||
} |
||||
} |
||||
XElement supportedRuntime = startup.Element("supportedRuntime"); |
||||
if (supportedRuntime == null) { |
||||
supportedRuntime = startup.AddFirstWithIndentation(new XElement("supportedRuntime")); |
||||
} |
||||
supportedRuntime.SetAttributeValue("version", newFramework.SupportedRuntimeVersion); |
||||
supportedRuntime.SetAttributeValue("sku", newFramework.SupportedSku); |
||||
} |
||||
} |
||||
} |
||||
|
||||
protected virtual void AddOrRemoveExtensions() |
||||
{ |
||||
} |
||||
|
||||
#region CreateProjectItem
|
||||
/// <summary>
|
||||
/// Creates a new projectItem for the passed itemType
|
||||
/// </summary>
|
||||
public override ProjectItem CreateProjectItem(IProjectItemBackendStore item) |
||||
{ |
||||
switch (item.ItemType.ItemName) { |
||||
case "Reference": |
||||
return new ReferenceProjectItem(Project, item); |
||||
case "ProjectReference": |
||||
return new ProjectReferenceProjectItem(Project, item); |
||||
case "COMReference": |
||||
return new ComReferenceProjectItem(Project, item); |
||||
case "Import": |
||||
return new ImportProjectItem(Project, item); |
||||
|
||||
case "None": |
||||
case "Compile": |
||||
case "EmbeddedResource": |
||||
case "Resource": |
||||
case "Content": |
||||
case "Folder": |
||||
return new FileProjectItem(Project, item); |
||||
|
||||
case "WebReferenceUrl": |
||||
return new WebReferenceUrl(Project, item); |
||||
|
||||
case "WebReferences": |
||||
return new WebReferencesProjectItem(Project, item); |
||||
|
||||
case "WCFMetadata": |
||||
return new ServiceReferencesProjectItem(Project, item); |
||||
|
||||
case "WCFMetadataStorage": |
||||
return new ServiceReferenceProjectItem(Project, item); |
||||
|
||||
default: |
||||
if (Project.AvailableFileItemTypes.Contains(item.ItemType) |
||||
|| SafeFileExists(Project.Directory, item.EvaluatedInclude)) |
||||
return new FileProjectItem(Project, item); |
||||
|
||||
return base.CreateProjectItem(item); |
||||
} |
||||
} |
||||
|
||||
static bool SafeFileExists(string directory, string fileName) |
||||
{ |
||||
try { |
||||
return File.Exists(Path.Combine(directory, fileName)); |
||||
} catch (Exception) { |
||||
return false; |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
#region Starting (debugging)
|
||||
public string StartProgram { |
||||
get { |
||||
return ((MSBuildBasedProject)Project).GetEvaluatedProperty("StartProgram") ?? ""; |
||||
} |
||||
set { |
||||
((MSBuildBasedProject)Project).SetProperty("StartProgram", string.IsNullOrEmpty(value) ? null : value); |
||||
} |
||||
} |
||||
|
||||
public string StartUrl { |
||||
get { |
||||
return ((MSBuildBasedProject)Project).GetEvaluatedProperty("StartURL") ?? ""; |
||||
} |
||||
set { |
||||
((MSBuildBasedProject)Project).SetProperty("StartURL", string.IsNullOrEmpty(value) ? null : value); |
||||
} |
||||
} |
||||
|
||||
public StartAction StartAction { |
||||
get { |
||||
try { |
||||
return (StartAction)Enum.Parse(typeof(StartAction), ((MSBuildBasedProject)Project).GetEvaluatedProperty("StartAction") ?? "Project"); |
||||
} catch (ArgumentException) { |
||||
return StartAction.Project; |
||||
} |
||||
} |
||||
set { |
||||
((MSBuildBasedProject)Project).SetProperty("StartAction", value.ToString()); |
||||
} |
||||
} |
||||
|
||||
public string StartArguments { |
||||
get { |
||||
return ((MSBuildBasedProject)Project).GetEvaluatedProperty("StartArguments") ?? ""; |
||||
} |
||||
set { |
||||
((MSBuildBasedProject)Project).SetProperty("StartArguments", string.IsNullOrEmpty(value) ? null : value); |
||||
} |
||||
} |
||||
|
||||
public string StartWorkingDirectory { |
||||
get { |
||||
return ((MSBuildBasedProject)Project).GetEvaluatedProperty("StartWorkingDirectory") ?? ""; |
||||
} |
||||
set { |
||||
((MSBuildBasedProject)Project).SetProperty("StartWorkingDirectory", string.IsNullOrEmpty(value) ? null : value); |
||||
} |
||||
} |
||||
#endregion
|
||||
} |
||||
} |
Loading…
Reference in new issue