///
/// Copyright © 2003-2008 JetBrains s.r.o.
/// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder).
///
using System;
using System.Diagnostics;
using System.Threading;
using JetBrains.Build.Common.Infra;
using Microsoft.Build.Framework;
using Microsoft.Win32;
namespace JetBrains.Build.Common.Tasks
{
///
/// Runs the DEVENV application.
///
public class StartDevenv : VsHiveTask
{
#region Attributes
///
/// Gets or sets the command-line arguments for the DEVENV application.
///
[Required]
public string Arguments
{
get
{
return (string)Bag[AttributeName.Arguments];
}
set
{
if(value == null)
throw new ArgumentNullException("value");
Bag[AttributeName.Arguments] = value;
}
}
///
/// Gets or sets whether the operation should be performed asynchronously.
/// If sync, we wait for Devenv to finish. Otherwise, we do not.
///
[Required]
public bool Async
{
get
{
return (bool)(Bag[AttributeName.Async] ?? false);
}
set
{
Bag[AttributeName.Async] = value;
}
}
///
/// Gets or sets the name of the executable to run.
/// It may differ for the development Visual Studio.
/// Optional.
///
public string DevenvExecutableName
{
get
{
return (string)Bag[AttributeName.DevenvExecutableName];
}
set
{
Bag[AttributeName.DevenvExecutableName] = value;
}
}
#endregion
#region Implementation
///
/// Gets the DEVENV installation folder.
///
protected string GetDevenvInstallDir()
{
using(RegistryKey key = Registry.LocalMachine.OpenSubKey(string.Format("SOFTWARE\\Microsoft\\VisualStudio\\{0}", GetVsHive()), false))
return (string)key.GetValue("InstallDir");
}
///
/// Gets the devenv command line argument that specifies the hive (with a trailing space). Could be an empty string.
///
protected string GetHiveArgument()
{
if(string.IsNullOrEmpty(GetVsRootSuffix()))
return "";
return string.Format("/RootSuffix {0} ", GetVsRootSuffix());
}
///
/// Picks the name from attrs, or uses the default.
///
private string GetDevenvExecutableName()
{
return Bag[AttributeName.DevenvExecutableName] as string ?? "devenv.exe";
}
#endregion
#region Overrides
///
/// The method to be overriden in inheriting tasks.
/// Throw an exception in case of an errror.
///
protected override void ExecuteTask()
{
// Prepare
var process = new Process();
var si = new ProcessStartInfo();
si.FileName = GetDevenvInstallDir() + GetDevenvExecutableName();
si.Arguments = GetHiveArgument() + GetStringValue(AttributeName.Arguments);
si.ErrorDialog = false;
si.CreateNoWindow = true;
process.StartInfo = si;
// Start
Log.LogMessage("Starting “{0}” with cmdline “{1}”{2}.", si.FileName, si.Arguments, (Async ? "" : ", waiting for the process to finish"));
if(!process.Start())
throw new InvalidOperationException(string.Format("The process has refused to start without specifying an error code."));
// Wait for, if sync
if(!Async)
{
while(!process.HasExited)
Thread.Sleep(100);
if(process.ExitCode == 0)
Log.LogMessage("The process has completed its execution.");
else
throw new InvalidOperationException(string.Format("The process “{0}” cmdline “{1}” has failed with exit code {2}.", si.FileName, si.Arguments, process.ExitCode));
}
}
#endregion
}
}