Skip to content
Permalink
Browse files

[Install] Prerequisites installer: improve error reporting and retrie…

…s (i.e. UAC not clicked) when installing Visual Studio or Build Tools
  • Loading branch information
xen2 committed Jan 23, 2019
1 parent 59c6713 commit 3d29a4f0d3b0e9bbda26e81932a8f7c2e7587176
Showing with 45 additions and 33 deletions.
  1. +45 −33 sources/tools/Xenko.PackageInstall/Program.cs
@@ -2,6 +2,7 @@
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
@@ -37,29 +38,7 @@ static int Main(string[] args)
var prerequisitesInstallerPath = @"install-prerequisites.exe";
if (File.Exists(prerequisitesInstallerPath))
{
var prerequisitesInstalled = false;
while (!prerequisitesInstalled)
{
try
{
var prerequisitesInstallerProcess = Process.Start(prerequisitesInstallerPath);
if (prerequisitesInstallerProcess == null)
throw new InvalidOperationException();
prerequisitesInstallerProcess.WaitForExit();
if (prerequisitesInstallerProcess.ExitCode != 0)
throw new InvalidOperationException();
prerequisitesInstalled = true;
}
catch
{
// We'll enter this if UAC has been declined, but also if it timed out (which is a frequent case
// if you don't stay in front of your computer during the installation.
var result = MessageBox.Show("The installation of prerequisites has been canceled by user or failed to run. Do you want to run it again?", "Error",
MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result != DialogResult.Yes)
break;
}
}
RunProgramAndAskUntilSuccess("prerequisites", prerequisitesInstallerPath, string.Empty);
}

// Make sure we have the proper VS2017/BuildTools prerequisites
@@ -78,6 +57,45 @@ static int Main(string[] args)
}
}

private static int RunProgramAndAskUntilSuccess(string programName, string fileName, string arguments)
{
TryAgain:
try
{
var prerequisitesInstallerProcess = Process.Start(fileName, arguments);
if (prerequisitesInstallerProcess == null)
{
MessageBox.Show($"The installation of {programName} failed (file not found).", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return -1;
}
prerequisitesInstallerProcess.WaitForExit();
if (prerequisitesInstallerProcess.ExitCode != 0)
{
// We'll enter this if UAC has been declined, but also if it timed out (which is a frequent case)
// if you don't stay in front of your computer during the installation.
var result = MessageBox.Show($"The installation of {programName} returned with code {prerequisitesInstallerProcess.ExitCode}.\r\nDo you want to try it again?", "Error", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result != DialogResult.Yes)
return prerequisitesInstallerProcess.ExitCode;
goto TryAgain;
}
return 0;
}
catch (Win32Exception e) when (e.NativeErrorCode == 1223)
{
// We'll enter this if UAC has been declined, but also if it timed out (which is a frequent case)
// if you don't stay in front of your computer during the installation.
var result = MessageBox.Show($"The installation of {programName} failed to run (UAC denied).\r\nDo you want to try it again?", "Error", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result != DialogResult.Yes)
return -1;
goto TryAgain;
}
catch (Exception e)
{
MessageBox.Show($"The installation of {programName} failed unexpectedly:\r\n\r\n{e}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return -1;
}
}

private static void CheckVisualStudioAndBuildTools()
{
// Check if there is any VS2017 installed with necessary workloads
@@ -94,12 +112,9 @@ private static void CheckVisualStudioAndBuildTools()
var vsInstallerPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"Microsoft Visual Studio\Installer\vs_installer.exe");
if (AllowVisualStudioOnly && existingVisualStudio2017Install != null && File.Exists(vsInstallerPath))
{
var vsInstaller = Process.Start(vsInstallerPath, $"modify --passive --norestart --installPath \"{existingVisualStudio2017Install.InstallationPath}\" {string.Join(" ", NecessaryVS2017Workloads.Select(x => $"--add {x}"))}");
if (vsInstaller == null)
throw new InvalidOperationException("Could not run vs_installer.exe");
vsInstaller.WaitForExit();

MessageBox.Show("Visual Studio 2017 was missing the .NET desktop develpment workload.\r\nWe highly recommend a reboot after the installation is finished, otherwise Xenko projects won't compile.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
var vsInstallerExitCode = RunProgramAndAskUntilSuccess("Visual Studio", vsInstallerPath, $"modify --passive --norestart --installPath \"{existingVisualStudio2017Install.InstallationPath}\" {string.Join(" ", NecessaryVS2017Workloads.Select(x => $"--add {x}"))}");
if (vsInstallerExitCode == 0)
MessageBox.Show("Visual Studio 2017 was missing the .NET desktop develpment workload.\r\nWe highly recommend a reboot after the installation is finished, otherwise Xenko projects won't compile.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
@@ -125,10 +140,7 @@ private static void CheckVisualStudioAndBuildTools()
if (buildToolsCommandLine != null)
{
// Run vs_buildtools again
var vsBuildToolsInstaller = Process.Start("vs_buildtools.exe", buildToolsCommandLine);
if (vsBuildToolsInstaller == null)
throw new InvalidOperationException("Could not run vs_buildtools installer");
vsBuildToolsInstaller.WaitForExit();
RunProgramAndAskUntilSuccess("Build Tools", "vs_buildtools.exe", buildToolsCommandLine);
}
}
}

0 comments on commit 3d29a4f

Please sign in to comment.
You can’t perform that action at this time.