diff --git a/Conan.VisualStudio.Core/ConanPathHelper.cs b/Conan.VisualStudio.Core/ConanPathHelper.cs index c069235f..42bfce76 100644 --- a/Conan.VisualStudio.Core/ConanPathHelper.cs +++ b/Conan.VisualStudio.Core/ConanPathHelper.cs @@ -32,15 +32,8 @@ public static bool ValidateConanExecutable(string exe, out string errorMessage) return true; try { - var startInfo = new ProcessStartInfo - { - FileName = exe, - Arguments = "--version", - UseShellExecute = false, - RedirectStandardInput = true, - RedirectStandardOutput = true, - CreateNoWindow = true - }; + var conan = new ConanRunner(exe); + var startInfo = conan.Version(); var process = Process.Start(startInfo); process.WaitForExit(); diff --git a/Conan.VisualStudio.Core/ConanRunner.cs b/Conan.VisualStudio.Core/ConanRunner.cs index f26ed84d..49f02016 100644 --- a/Conan.VisualStudio.Core/ConanRunner.cs +++ b/Conan.VisualStudio.Core/ConanRunner.cs @@ -34,6 +34,20 @@ private string BuildOptions(ConanBuildType build, bool update) return options; } + public ProcessStartInfo Version() + { + var startInfo = new ProcessStartInfo + { + FileName = _executablePath, + Arguments = "--version", + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = true + }; + return startInfo; + } + public ProcessStartInfo Install(ConanProject project, ConanConfiguration configuration, ConanGeneratorType generator, ConanBuildType build, bool update, Core.IErrorListService errorListService) { string ProcessArgument(string name, string value) => $"-s {name}={Escape(value)}"; diff --git a/Conan.VisualStudio/Conan.VisualStudio.csproj b/Conan.VisualStudio/Conan.VisualStudio.csproj index bada0e30..628ba9d2 100644 --- a/Conan.VisualStudio/Conan.VisualStudio.csproj +++ b/Conan.VisualStudio/Conan.VisualStudio.csproj @@ -89,6 +89,7 @@ source.extension.vsixmanifest + True @@ -306,4 +307,4 @@ --> - + \ No newline at end of file diff --git a/Conan.VisualStudio/Services/ConanService.cs b/Conan.VisualStudio/Services/ConanService.cs index 6b1d0621..90a07ed9 100644 --- a/Conan.VisualStudio/Services/ConanService.cs +++ b/Conan.VisualStudio/Services/ConanService.cs @@ -109,22 +109,6 @@ public async Task InstallAsync(VCProject vcProject) return await InstallDependenciesAsync(conan, project); } - private static void AppendLinesFunc(object packedParams) - { - var paramsTuple = (Tuple)packedParams; - StreamWriter writer = paramsTuple.Item1; - StreamReader reader = paramsTuple.Item2; - - string line; - while ((line = reader.ReadLine()) != null) - { - lock (writer) - { - Logger.Log(line); - writer.WriteLine(line); - } - } - } private async Task InstallDependenciesAsync(ConanRunner conan, ConanProject project) { @@ -141,55 +125,47 @@ private async Task InstallDependenciesAsync(ConanRunner conan, ConanProjec ConanBuildType build = _settingsService.GetConanBuild(); bool update = _settingsService.GetConanUpdate(); - ProcessStartInfo process = conan.Install(project, configuration, generator, build, update, _errorListService); - - string message = $"[Conan.VisualStudio] Calling process '{process.FileName}' " + - $"with arguments '{process.Arguments}'"; - Logger.Log(message); - await logStream.WriteLineAsync(message); - + ProcessStartInfo process = null; try { - using (Process exeProcess = Process.Start(process)) + // Run 'conan --version' for log purposes + process = conan.Version(); + int exitCode = await Utils.RunProcessAsync(process, logStream); + if (exitCode != 0) + { + string message = "Cannot get Conan version, check that the " + + "executable is pointing to a valid one"; + Logger.Log(message); + await logStream.WriteLineAsync(message); + _errorListService.WriteError(message, logFilePath); + } + + // Run the install + process = conan.Install(project, configuration, generator, build, update, _errorListService); + exitCode = await Utils.RunProcessAsync(process, logStream); + if (exitCode != 0) + { + string message = $"Conan has returned exit code '{exitCode}' " + + $"while processing configuration '{configuration}'. " + + $"Please check file '{logFilePath}' for details."; + + Logger.Log(message); + await logStream.WriteLineAsync(message); + _errorListService.WriteError(message, logFilePath); + return false; + } + else { - var tokenSource = new CancellationTokenSource(); - var token = tokenSource.Token; - - Task outputReader = Task.Factory.StartNew(AppendLinesFunc, - Tuple.Create(logStream, exeProcess.StandardOutput), - token, TaskCreationOptions.None, TaskScheduler.Default); - Task errorReader = Task.Factory.StartNew(AppendLinesFunc, - Tuple.Create(logStream, exeProcess.StandardError), - token, TaskCreationOptions.None, TaskScheduler.Default); - - int exitCode = await exeProcess.WaitForExitAsync(); - - Task.WaitAll(outputReader, errorReader); - - if (exitCode != 0) - { - message = $"Conan has returned exit code '{exitCode}' " + - $"while processing configuration '{configuration}'. " + - $"Please check file '{logFilePath}' for details."; - - Logger.Log(message); - await logStream.WriteLineAsync(message); - _errorListService.WriteError(message, logFilePath); - return false; - } - else - { - message = $"[Conan.VisualStudio] Conan has succsessfully " + - $"installed configuration '{configuration}'"; - Logger.Log(message); - await logStream.WriteLineAsync(message); - _errorListService.WriteMessage(message); - } + string message = $"[Conan.VisualStudio] Conan has succsessfully " + + $"installed configuration '{configuration}'"; + Logger.Log(message); + await logStream.WriteLineAsync(message); + _errorListService.WriteMessage(message); } } - catch(System.ComponentModel.Win32Exception e) + catch (System.ComponentModel.Win32Exception e) { - message = $"[Conan.VisualStudio] Unhandled error running '{process.FileName}'" + + string message = $"[Conan.VisualStudio] Unhandled error running '{process.FileName}'" + $": {e.Message}. Check log file '{logFilePath}' for details"; Logger.Log(message); await logStream.WriteLineAsync(message); diff --git a/Conan.VisualStudio/Utils.cs b/Conan.VisualStudio/Utils.cs new file mode 100644 index 00000000..5d35ecc5 --- /dev/null +++ b/Conan.VisualStudio/Utils.cs @@ -0,0 +1,56 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.VisualStudio.Threading; + +namespace Conan.VisualStudio +{ + public static class Utils + { + private static void AppendLinesFunc(object packedParams) + { + var paramsTuple = (Tuple)packedParams; + StreamWriter writer = paramsTuple.Item1; + StreamReader reader = paramsTuple.Item2; + + string line; + while ((line = reader.ReadLine()) != null) + { + lock (writer) + { + Logger.Log(line); + writer.WriteLine(line); + } + } + } + + public static async Task RunProcessAsync(ProcessStartInfo process, StreamWriter logStream) + { + string message = $"[Conan.VisualStudio] Calling process '{process.FileName}' " + + $"with arguments '{process.Arguments}'"; + Logger.Log(message); + await logStream.WriteLineAsync(message); + + using (Process exeProcess = Process.Start(process)) + { + var tokenSource = new CancellationTokenSource(); + var token = tokenSource.Token; + + Task outputReader = Task.Factory.StartNew(AppendLinesFunc, + Tuple.Create(logStream, exeProcess.StandardOutput), + token, TaskCreationOptions.None, TaskScheduler.Default); + Task errorReader = Task.Factory.StartNew(AppendLinesFunc, + Tuple.Create(logStream, exeProcess.StandardError), + token, TaskCreationOptions.None, TaskScheduler.Default); + + int exitCode = await exeProcess.WaitForExitAsync(); + + Task.WaitAll(outputReader, errorReader); + + return exitCode; + } + } + } +}