Index: core/tasks/DevenvTask.cs =================================================================== --- core/tasks/DevenvTask.cs (revision 2631) +++ core/tasks/DevenvTask.cs (working copy) @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.IO; using Exortech.NetReflector; using ThoughtWorks.CruiseControl.Core.Util; @@ -14,6 +15,7 @@ public const int DEFAULT_BUILD_TIMEOUT = 600; public const string DEFAULT_BUILDTYPE = "rebuild"; public const string DEFAULT_PROJECT = ""; + public const ProcessPriorityClass DEFAULT_PRIORITY = ProcessPriorityClass.Normal; private IRegistry registry; private ProcessExecutor executor; @@ -66,6 +68,9 @@ [ReflectorProperty("project", Required = false)] public string Project = DEFAULT_PROJECT; + [ReflectorProperty("priority", Required = false)] + public ProcessPriorityClass Priority = DEFAULT_PRIORITY; + public virtual void Run(IIntegrationResult result) { ProcessResult processResult = AttemptToExecute(result.WorkingDirectory); @@ -80,7 +85,7 @@ private ProcessResult AttemptToExecute(string workingDirectory) { - ProcessInfo processInfo = new ProcessInfo(Executable, Arguments, workingDirectory); + ProcessInfo processInfo = new ProcessInfo(Executable, Arguments, workingDirectory, Priority); processInfo.TimeOut = BuildTimeoutSeconds * 1000; Log.Info(string.Format("Starting build: {0} {1}", processInfo.FileName, processInfo.Arguments)); Index: core/tasks/ExecutableTask.cs =================================================================== --- core/tasks/ExecutableTask.cs (revision 2631) +++ core/tasks/ExecutableTask.cs (working copy) @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.IO; using Exortech.NetReflector; using ThoughtWorks.CruiseControl.Core.Util; @@ -34,6 +35,9 @@ [ReflectorProperty("buildArgs", Required = false)] public string BuildArgs = string.Empty; + [ReflectorProperty("priority", Required = false)] + public ProcessPriorityClass Priority = ProcessPriorityClass.Normal; + /// /// Gets and sets the maximum number of seconds that the build may take. If the build process takes longer than /// this period, it will be killed. Specify this value as zero to disable process timeouts. @@ -54,7 +58,7 @@ private ProcessInfo NewProcessInfoFrom(IIntegrationResult result) { - ProcessInfo info = new ProcessInfo(Executable, BuildArgs, BaseDirectory(result)); + ProcessInfo info = new ProcessInfo(Executable, BuildArgs, BaseDirectory(result), Priority); info.TimeOut = BuildTimeoutSeconds*1000; foreach (string key in result.IntegrationProperties.Keys) { Index: core/tasks/MsBuildTask.cs =================================================================== --- core/tasks/MsBuildTask.cs (revision 2631) +++ core/tasks/MsBuildTask.cs (working copy) @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.IO; using System.Collections; using Exortech.NetReflector; @@ -12,6 +13,7 @@ public const string DefaultLogger = "ThoughtWorks.CruiseControl.MsBuild.XmlLogger,ThoughtWorks.CruiseControl.MsBuild.dll"; public const string LogFilename = "msbuild-results.xml"; public const int DefaultTimeout = 600; + public const ProcessPriorityClass DefaultPriority = ProcessPriorityClass.Normal; private readonly ProcessExecutor executor; @@ -44,6 +46,9 @@ [ReflectorProperty("timeout", Required=false)] public int Timeout = DefaultTimeout; + [ReflectorProperty("priority", Required = false)] + public ProcessPriorityClass Priority = DefaultPriority; + public void Run(IIntegrationResult result) { ProcessResult processResult = executor.Execute(NewProcessInfo(result)); @@ -57,7 +62,7 @@ private ProcessInfo NewProcessInfo(IIntegrationResult result) { - ProcessInfo info = new ProcessInfo(Executable, Args(result), result.BaseFromWorkingDirectory(WorkingDirectory)); + ProcessInfo info = new ProcessInfo(Executable, Args(result), result.BaseFromWorkingDirectory(WorkingDirectory), Priority); info.TimeOut = Timeout*1000; return info; } Index: core/tasks/NAntTask.cs =================================================================== --- core/tasks/NAntTask.cs (revision 2631) +++ core/tasks/NAntTask.cs (working copy) @@ -1,5 +1,6 @@ using System; using System.Collections; +using System.Diagnostics; using System.IO; using System.Text; using Exortech.NetReflector; @@ -14,7 +15,8 @@ public const string DefaultExecutable = "nant.exe"; public const string DefaultLogger = "NAnt.Core.XmlLogger"; public const bool DefaultNoLogo = true; - + public const ProcessPriorityClass DefaultPriority = ProcessPriorityClass.Normal; + private ProcessExecutor executor; public NAntTask() : this(new ProcessExecutor()) @@ -47,6 +49,9 @@ [ReflectorProperty("nologo", Required = false)] public bool NoLogo = DefaultNoLogo; + [ReflectorProperty("priority", Required = false)] + public ProcessPriorityClass Priority = DefaultPriority; + /// /// Gets and sets the maximum number of seconds that the build may take. If the build process takes longer than /// this period, it will be killed. Specify this value as zero to disable process timeouts. @@ -74,7 +79,7 @@ private ProcessInfo CreateProcessInfo(IIntegrationResult result) { - ProcessInfo info = new ProcessInfo(Executable, CreateArgs(result), BaseDirectory(result)); + ProcessInfo info = new ProcessInfo(Executable, CreateArgs(result), BaseDirectory(result), Priority); info.TimeOut = BuildTimeoutSeconds*1000; return info; } Index: core/tasks/NUnitTask.cs =================================================================== --- core/tasks/NUnitTask.cs (revision 2631) +++ core/tasks/NUnitTask.cs (working copy) @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.IO; using Exortech.NetReflector; using ThoughtWorks.CruiseControl.Core.Util; @@ -10,6 +11,7 @@ public const string DefaultPath = @"C:\Program Files\NUnit 2.2\bin\nunit-console.exe"; public const int DefaultTimeout = 600; private const string DefaultOutputFile = "nunit-results.xml"; + public const ProcessPriorityClass DefaultPriority = ProcessPriorityClass.Normal; private ProcessExecutor processExecutor; public NUnitTask() : this(new ProcessExecutor()) @@ -32,6 +34,9 @@ [ReflectorProperty("timeout", Required=false)] public int Timeout = DefaultTimeout; + [ReflectorProperty("priority", Required = false)] + public ProcessPriorityClass Priority = DefaultPriority; + public virtual void Run(IIntegrationResult result) { string outputFile = result.BaseFromArtifactsDirectory(OutputFile); @@ -53,7 +58,7 @@ string args = new NUnitArgument(Assemblies, outputFile).ToString(); Log.Debug(string.Format("Running unit tests: {0} {1}", NUnitPath, args)); - ProcessInfo info = new ProcessInfo(NUnitPath, args, result.WorkingDirectory); + ProcessInfo info = new ProcessInfo(NUnitPath, args, result.WorkingDirectory, Priority); info.TimeOut = Timeout * 1000; return info; } Index: core/util/ProcessExecutor.cs =================================================================== --- core/util/ProcessExecutor.cs (revision 2631) +++ core/util/ProcessExecutor.cs (working copy) @@ -51,6 +51,15 @@ try { bool isNewProcess = process.Start(); + try + { + process.PriorityClass = processInfo.Priority; + } + catch (Exception) + { + // in case process has already ended + // + } if (! isNewProcess) Log.Debug("Reusing existing process..."); } catch (Win32Exception e) Index: core/util/ProcessInfo.cs =================================================================== --- core/util/ProcessInfo.cs (revision 2631) +++ core/util/ProcessInfo.cs (working copy) @@ -12,6 +12,7 @@ private ProcessStartInfo startInfo = new ProcessStartInfo(); private string standardInputContent = null; private int timeout = DefaultTimeout; + public ProcessPriorityClass Priority; public ProcessInfo(string filename) : this(filename, null) {} @@ -19,7 +20,10 @@ public ProcessInfo(string filename, string arguments) : this(filename, arguments, null) {} - public ProcessInfo(string filename, string arguments, string workingDirectory) + public ProcessInfo(string filename, string arguments, string workingDirectory) : this(filename, arguments, workingDirectory, ProcessPriorityClass.Normal) + { } + + public ProcessInfo(string filename, string arguments, string workingDirectory, ProcessPriorityClass priority) { startInfo.FileName = StringUtil.StripQuotes(filename); startInfo.Arguments = arguments; @@ -29,6 +33,7 @@ startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardError = true; startInfo.RedirectStandardInput = false; + this.Priority = priority; RepathExecutableIfItIsInWorkingDirectory(); } Index: UnitTests/Core/Tasks/DevenvTaskTest.cs =================================================================== --- UnitTests/Core/Tasks/DevenvTaskTest.cs (revision 2631) +++ UnitTests/Core/Tasks/DevenvTaskTest.cs (working copy) @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.IO; using Exortech.NetReflector; using NMock; @@ -47,6 +48,7 @@ 4 MyProject Clean + BelowNormal "; DevenvTask task = (DevenvTask) NetReflector.Read(xml); @@ -56,6 +58,7 @@ Assert.AreEqual(4, task.BuildTimeoutSeconds); Assert.AreEqual(@"Clean", task.BuildType); Assert.AreEqual(@"MyProject", task.Project); + Assert.AreEqual(ProcessPriorityClass.BelowNormal, task.Priority); } [Test] Index: UnitTests/Core/Tasks/ExecutableTaskTest.cs =================================================================== --- UnitTests/Core/Tasks/ExecutableTaskTest.cs (revision 2631) +++ UnitTests/Core/Tasks/ExecutableTaskTest.cs (working copy) @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.IO; using Exortech.NetReflector; using NMock.Constraints; @@ -37,6 +38,7 @@ C:\ myarg1 myarg2 123 + BelowNormal "; task = (ExecutableTask) NetReflector.Read(xml); @@ -44,6 +46,7 @@ Assert.AreEqual("mybatchfile.bat", task.Executable); Assert.AreEqual(123, task.BuildTimeoutSeconds); Assert.AreEqual("myarg1 myarg2", task.BuildArgs); + Assert.AreEqual(ProcessPriorityClass.BelowNormal, task.Priority); Verify(); } Index: UnitTests/Core/Tasks/MsBuildTaskTest.cs =================================================================== --- UnitTests/Core/Tasks/MsBuildTaskTest.cs (revision 2631) +++ UnitTests/Core/Tasks/MsBuildTaskTest.cs (working copy) @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.IO; using Exortech.NetReflector; using NUnit.Framework; @@ -72,7 +73,7 @@ // NOTE: Property names are sorted alphabetically when passed as process arguments // Tests that look for the correct arguments will fail if the following properties // are not sorted alphabetically. - string expectedProperties = string.Format(@"/p:CCNetArtifactDirectory={2};CCNetBuildCondition=NoBuild;CCNetBuildDate={0};CCNetBuildTime={1};CCNetIntegrationStatus=Success;CCNetLabel=My Label;CCNetLastIntegrationStatus=Unknown;CCNetNumericLabel=0;CCNetProject=test;CCNetWorkingDirectory=c:\source\",testDateString, testTimeString, result.ArtifactDirectory); + string expectedProperties = string.Format(@"/p:CCNetArtifactDirectory={2};CCNetBuildCondition=NoBuild;CCNetBuildDate={0};CCNetBuildTime={1};CCNetFailureUsers=System.Collections.ArrayList;CCNetIntegrationStatus=Success;CCNetLabel=My Label;CCNetLastIntegrationStatus=Unknown;CCNetNumericLabel=0;CCNetProject=test;CCNetWorkingDirectory=c:\source\",testDateString, testTimeString, result.ArtifactDirectory); ExpectToExecuteArguments(@"/nologo " + @"""" + expectedProperties + @"""" + DefaultLogger()); result.Label = @"My Label"; task.Run(result); @@ -137,6 +138,7 @@ Build;Test 15 Kobush.Build.Logging.XmlLogger,Kobush.MSBuild.dll;buildresult.xml + BelowNormal "; task = (MsBuildTask) NetReflector.Read(xml); Assert.AreEqual(@"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50215\MSBuild.exe", task.Executable); @@ -146,6 +148,7 @@ Assert.AreEqual("/p:Configuration=Debug /v:diag", task.BuildArgs); Assert.AreEqual(15, task.Timeout); Assert.AreEqual("Kobush.Build.Logging.XmlLogger,Kobush.MSBuild.dll;buildresult.xml", task.Logger); + Assert.AreEqual(ProcessPriorityClass.BelowNormal, task.Priority); } [Test] @@ -167,7 +170,7 @@ // NOTE: Property names are sorted alphabetically when passed as process arguments // Tests that look for the correct arguments will fail if the following properties // are not sorted alphabetically. - return string.Format(@"/p:CCNetArtifactDirectory={3};CCNetBuildCondition=NoBuild;CCNetBuildDate={1};CCNetBuildTime={2};CCNetIntegrationStatus=Success;CCNetLabel=1.0;CCNetLastIntegrationStatus=Unknown;CCNetNumericLabel=0;CCNetProject=test;CCNetWorkingDirectory={0}", DefaultWorkingDirectory, testDateString, testTimeString, result.ArtifactDirectory); + return string.Format(@"/p:CCNetArtifactDirectory={3};CCNetBuildCondition=NoBuild;CCNetBuildDate={1};CCNetBuildTime={2};CCNetFailureUsers=System.Collections.ArrayList;CCNetIntegrationStatus=Success;CCNetLabel=1.0;CCNetLastIntegrationStatus=Unknown;CCNetNumericLabel=0;CCNetProject=test;CCNetWorkingDirectory={0}", DefaultWorkingDirectory, testDateString, testTimeString, result.ArtifactDirectory); } } } \ No newline at end of file Index: UnitTests/Core/Tasks/NAntTaskTest.cs =================================================================== --- UnitTests/Core/Tasks/NAntTaskTest.cs (revision 2631) +++ UnitTests/Core/Tasks/NAntTaskTest.cs (working copy) @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.IO; using Exortech.NetReflector; using NMock.Constraints; @@ -46,6 +47,7 @@ SourceForge.NAnt.XmlLogger 123 FALSE + BelowNormal "; NetReflector.Read(xml, builder); @@ -57,6 +59,7 @@ Assert.AreEqual("SourceForge.NAnt.XmlLogger", builder.Logger); Assert.AreEqual("foo", builder.Targets[0]); Assert.AreEqual(false, builder.NoLogo); + Assert.AreEqual(ProcessPriorityClass.BelowNormal, builder.Priority); } [Test] @@ -254,7 +257,7 @@ // NOTE: Property names are sorted alphabetically when passed as process arguments // Tests that look for the correct arguments will fail if the following properties // are not sorted alphabetically. - return string.Format(@"-D:CCNetArtifactDirectory={1} -D:CCNetBuildCondition=NoBuild -D:CCNetBuildDate={2} -D:CCNetBuildTime={3} -D:CCNetIntegrationStatus=Success -D:CCNetLabel=1.0 -D:CCNetLastIntegrationStatus=Unknown -D:CCNetNumericLabel=0 -D:CCNetProject=test -D:CCNetWorkingDirectory={0}", workingDirectory, artifactDirectory, testDateString, testTimeString); + return string.Format(@"-D:CCNetArtifactDirectory={1} -D:CCNetBuildCondition=NoBuild -D:CCNetBuildDate={2} -D:CCNetBuildTime={3} -D:CCNetFailureUsers=System.Collections.ArrayList -D:CCNetIntegrationStatus=Success -D:CCNetLabel=1.0 -D:CCNetLastIntegrationStatus=Unknown -D:CCNetNumericLabel=0 -D:CCNetProject=test -D:CCNetWorkingDirectory={0}", workingDirectory, artifactDirectory, testDateString, testTimeString); } } } \ No newline at end of file Index: UnitTests/Core/Tasks/NunitTaskTest.cs =================================================================== --- UnitTests/Core/Tasks/NunitTaskTest.cs (revision 2631) +++ UnitTests/Core/Tasks/NunitTaskTest.cs (working copy) @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.IO; using Exortech.NetReflector; using NUnit.Framework; @@ -22,6 +23,7 @@ c:\testfile.xml 50 + BelowNormal "; task = NetReflector.Read(xml) as NUnitTask; Assert.AreEqual(@"d:\temp\nunit-console.exe", task.NUnitPath); @@ -29,6 +31,7 @@ Assert.AreEqual("foo.dll", task.Assemblies[0]); Assert.AreEqual(@"c:\testfile.xml", task.OutputFile); Assert.AreEqual(50, task.Timeout); + Assert.AreEqual(ProcessPriorityClass.BelowNormal, task.Priority); } [Test] Index: UnitTests/Core/Util/ProcessExecutorTest.cs =================================================================== --- UnitTests/Core/Util/ProcessExecutorTest.cs (revision 2631) +++ UnitTests/Core/Util/ProcessExecutorTest.cs (working copy) @@ -67,7 +67,7 @@ [Test] public void ForceProcessTimeoutBecauseTargetIsNonTerminating() { - ProcessInfo processInfo = new ProcessInfo("cmd.exe", "/C pause"); + ProcessInfo processInfo = new ProcessInfo("cmd.exe", "/C sleep 1000"); processInfo.TimeOut = 10; ProcessResult result = executor.Execute(processInfo);