2015-11-25 01:48:58 +00:00
using System ;
2016-01-28 09:46:03 +00:00
using System.Diagnostics ;
using System.IO ;
2015-11-25 01:48:58 +00:00
using System.Linq ;
using Microsoft.Deployment.WindowsInstaller ;
using Microsoft.Deployment.WindowsInstaller.Package ;
namespace Dotnet.Cli.Msi.Tests
{
public class MsiManager
{
2016-01-28 09:46:03 +00:00
private string _bundleFile ;
2015-11-25 01:48:58 +00:00
private string _msiFile ;
private string _productCode ;
private InstallPackage _installPackage ;
public ProductInstallation Installation
{
get
{
return ProductInstallation . AllProducts . SingleOrDefault ( p = > p . ProductCode = = _productCode ) ;
}
}
public string InstallLocation
{
get
{
return IsInstalled ? Installation . InstallLocation : null ;
}
}
public bool IsInstalled
{
get
{
var prodInstall = Installation ;
return Installation = = null ? false : prodInstall . IsInstalled ;
}
}
public string UpgradeCode
{
get
{
return _installPackage . Property [ "UpgradeCode" ] ;
}
}
public MsiManager ( string msiFile )
{
2016-01-28 09:46:03 +00:00
_bundleFile = Path . ChangeExtension ( msiFile , "exe" ) ;
2015-11-25 01:48:58 +00:00
_msiFile = msiFile ;
var ispackage = Installer . VerifyPackage ( msiFile ) ;
if ( ! ispackage )
{
throw new ArgumentException ( "Not a valid MSI file" , msiFile ) ;
}
_installPackage = new InstallPackage ( msiFile , DatabaseOpenMode . ReadOnly ) ;
_productCode = _installPackage . Property [ "ProductCode" ] ;
}
public bool Install ( string customLocation = null )
{
string dotnetHome = "" ;
if ( ! string . IsNullOrEmpty ( customLocation ) )
{
dotnetHome = $"DOTNETHOME={customLocation}" ;
}
2016-01-28 09:46:03 +00:00
RunBundle ( dotnetHome ) ;
2015-11-25 01:48:58 +00:00
return IsInstalled ;
}
public bool UnInstall ( )
{
if ( ! IsInstalled )
{
throw new InvalidOperationException ( $"UnInstall Error: Msi at {_msiFile} is not installed." ) ;
}
2016-01-28 09:46:03 +00:00
RunBundle ( "/uninstall" ) ;
2015-11-25 01:48:58 +00:00
return ! IsInstalled ;
}
2016-01-28 09:46:03 +00:00
private void RunBundle ( string additionalArguments )
{
var arguments = $"/q /norestart {additionalArguments}" ;
var process = Process . Start ( _bundleFile , arguments ) ;
if ( ! process . WaitForExit ( 5 * 60 * 1000 ) )
{
throw new InvalidOperationException ( $"Failed to wait for the installation operation to complete. Check to see if the installation process is still running. Command line: {_bundleFile} {arguments}" ) ;
}
else if ( 0 ! = process . ExitCode )
{
throw new InvalidOperationException ( $"The installation operation failed with exit code: {process.ExitCode}. Command line: {_bundleFile} {arguments}" ) ;
}
}
2015-11-25 01:48:58 +00:00
}
}