diff --git a/src/chocolatey/chocolatey.csproj b/src/chocolatey/chocolatey.csproj index 2daec58295..d820e9b50b 100644 --- a/src/chocolatey/chocolatey.csproj +++ b/src/chocolatey/chocolatey.csproj @@ -95,6 +95,7 @@ + diff --git a/src/chocolatey/infrastructure.app/domain/CustomInstaller.cs b/src/chocolatey/infrastructure.app/domain/CustomInstaller.cs index e4b98242dc..fe991be4b1 100644 --- a/src/chocolatey/infrastructure.app/domain/CustomInstaller.cs +++ b/src/chocolatey/infrastructure.app/domain/CustomInstaller.cs @@ -15,10 +15,9 @@ namespace chocolatey.infrastructure.app.domain { - using System; using System.Collections.Generic; - public class CustomInstaller : IInstaller + public class CustomInstaller : InstallerBase { public CustomInstaller() { @@ -32,34 +31,26 @@ public CustomInstaller() UninstallExecutable = "\"{0}\"".format_with(InstallTokens.UNINSTALLER_LOCATION); SilentUninstall = "/S"; OtherUninstallOptions = ""; - ValidExitCodes = new List {0}; + ValidInstallExitCodes = new List { 0 }; + ValidUninstallExitCodes = new List { 0 }; } - public InstallerType InstallerType + public override InstallerType InstallerType { get { return InstallerType.Custom; } } - public string InstallExecutable { get; private set; } - public string SilentInstall { get; private set; } - public string NoReboot { get; private set; } - public string LogFile { get; private set; } - public string CustomInstallLocation { get; private set; } - public string Language { get; private set; } - public string OtherInstallOptions { get; private set; } - public string UninstallExecutable { get; private set; } - public string SilentUninstall { get; private set; } - public string OtherUninstallOptions { get; private set; } - public IEnumerable ValidExitCodes { get; private set; } - - public string build_install_command_arguments() + public override string build_install_command_arguments(bool customInstallLocation, bool languageRequested) { - throw new NotImplementedException(); + if (customInstallLocation) this.Log().Warn("CustomInstaller doesn't support custom install locations."); + if (languageRequested) this.Log().Warn("CustomInstaller doesn't support custom language options."); + + return string.Empty; } - public string build_uninstall_command_arguments() + public override string build_uninstall_command_arguments() { - return "{0} {1}".format_with(SilentUninstall, OtherInstallOptions); + return string.Empty; } } } \ No newline at end of file diff --git a/src/chocolatey/infrastructure.app/domain/IInstaller.cs b/src/chocolatey/infrastructure.app/domain/IInstaller.cs index 273a88a852..84e3363cad 100644 --- a/src/chocolatey/infrastructure.app/domain/IInstaller.cs +++ b/src/chocolatey/infrastructure.app/domain/IInstaller.cs @@ -30,9 +30,10 @@ public interface IInstaller string UninstallExecutable { get; } string SilentUninstall { get; } string OtherUninstallOptions { get; } - IEnumerable ValidExitCodes { get; } + IEnumerable ValidInstallExitCodes { get; } + IEnumerable ValidUninstallExitCodes { get; } - string build_install_command_arguments(); + string build_install_command_arguments(bool customInstallLocation, bool languageRequested); string build_uninstall_command_arguments(); } } \ No newline at end of file diff --git a/src/chocolatey/infrastructure.app/domain/InnoSetupInstaller.cs b/src/chocolatey/infrastructure.app/domain/InnoSetupInstaller.cs index 1a5ec4d1e8..7428c3debf 100644 --- a/src/chocolatey/infrastructure.app/domain/InnoSetupInstaller.cs +++ b/src/chocolatey/infrastructure.app/domain/InnoSetupInstaller.cs @@ -24,7 +24,7 @@ namespace chocolatey.infrastructure.app.domain /// /// http://www.jrsoftware.org/ishelp/index.php?topic=setupcmdline /// - public class InnoSetupInstaller : IInstaller + public class InnoSetupInstaller : InstallerBase { public InnoSetupInstaller() { @@ -38,34 +38,14 @@ public InnoSetupInstaller() UninstallExecutable = "\"{0}\"".format_with(InstallTokens.UNINSTALLER_LOCATION); SilentUninstall = "/VERYSILENT"; OtherUninstallOptions = "/SUPPRESSMSGBOXES"; - ValidExitCodes = new List {0}; + // http://www.jrsoftware.org/ishelp/index.php?topic=setupexitcodes + ValidInstallExitCodes = new List { 0 }; + ValidUninstallExitCodes = new List { 0 }; } - public InstallerType InstallerType + public override InstallerType InstallerType { get { return InstallerType.InnoSetup; } } - - public string InstallExecutable { get; private set; } - public string SilentInstall { get; private set; } - public string NoReboot { get; private set; } - public string LogFile { get; private set; } - public string CustomInstallLocation { get; private set; } - public string Language { get; private set; } - public string OtherInstallOptions { get; private set; } - public string UninstallExecutable { get; private set; } - public string SilentUninstall { get; private set; } - public string OtherUninstallOptions { get; private set; } - public IEnumerable ValidExitCodes { get; private set; } - - public string build_install_command_arguments() - { - throw new NotImplementedException(); - } - - public string build_uninstall_command_arguments() - { - return "{0} {1} {2}".format_with(SilentUninstall, NoReboot, OtherUninstallOptions); - } } } \ No newline at end of file diff --git a/src/chocolatey/infrastructure.app/domain/InstallShieldInstaller.cs b/src/chocolatey/infrastructure.app/domain/InstallShieldInstaller.cs index 8b009073b3..f8be43d96d 100644 --- a/src/chocolatey/infrastructure.app/domain/InstallShieldInstaller.cs +++ b/src/chocolatey/infrastructure.app/domain/InstallShieldInstaller.cs @@ -17,6 +17,7 @@ namespace chocolatey.infrastructure.app.domain { using System; using System.Collections.Generic; + using System.Text; /// /// InstallShield Installer Options @@ -24,7 +25,7 @@ namespace chocolatey.infrastructure.app.domain /// /// http://helpnet.installshield.com/installshield18helplib/ihelpsetup_execmdline.htm /// - public class InstallShieldInstaller : IInstaller + public class InstallShieldInstaller : InstallerBase { public InstallShieldInstaller() { @@ -38,34 +39,14 @@ public InstallShieldInstaller() UninstallExecutable = "\"{0}\"".format_with(InstallTokens.UNINSTALLER_LOCATION); SilentUninstall = "/uninst /s"; OtherUninstallOptions = "/sms"; - ValidExitCodes = new List {0}; + // http://helpnet.installshield.com/installshield18helplib/IHelpSetup_EXEErrors.htm + ValidInstallExitCodes = new List { 0, 1641, 3010 }; + ValidUninstallExitCodes = new List { 0, 1641, 3010 }; } - public InstallerType InstallerType + public override InstallerType InstallerType { get { return InstallerType.InstallShield; } } - - public string InstallExecutable { get; private set; } - public string SilentInstall { get; private set; } - public string NoReboot { get; private set; } - public string LogFile { get; private set; } - public string CustomInstallLocation { get; private set; } - public string Language { get; private set; } - public string OtherInstallOptions { get; private set; } - public string UninstallExecutable { get; private set; } - public string SilentUninstall { get; private set; } - public string OtherUninstallOptions { get; private set; } - public IEnumerable ValidExitCodes { get; private set; } - - public string build_install_command_arguments() - { - throw new NotImplementedException(); - } - - public string build_uninstall_command_arguments() - { - return "{0} {1} {2}".format_with(SilentUninstall, NoReboot, OtherUninstallOptions); - } } } \ No newline at end of file diff --git a/src/chocolatey/infrastructure.app/domain/InstallerBase.cs b/src/chocolatey/infrastructure.app/domain/InstallerBase.cs new file mode 100644 index 0000000000..1fa8333102 --- /dev/null +++ b/src/chocolatey/infrastructure.app/domain/InstallerBase.cs @@ -0,0 +1,56 @@ +// Copyright © 2011 - Present RealDimensions Software, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace chocolatey.infrastructure.app.domain +{ + using System.Collections.Generic; + using System.Text; + + public abstract class InstallerBase : IInstaller + { + public abstract InstallerType InstallerType { get; } + + public string InstallExecutable { get; protected set; } + public string SilentInstall { get; protected set; } + public string NoReboot { get; protected set; } + public string LogFile { get; protected set; } + public string OtherInstallOptions { get; protected set; } + public string CustomInstallLocation { get; protected set; } + public string Language { get; protected set; } + public string UninstallExecutable { get; protected set; } + public string SilentUninstall { get; protected set; } + public string OtherUninstallOptions { get; protected set; } + public IEnumerable ValidInstallExitCodes { get; protected set; } + public IEnumerable ValidUninstallExitCodes { get; protected set; } + + public virtual string build_install_command_arguments(bool customInstallLocation, bool languageRequested) + { + var args = new StringBuilder(); + args.AppendFormat("{0} {1} {2}", SilentInstall, NoReboot, LogFile); + if (languageRequested) args.AppendFormat(" {0}", Language); + args.AppendFormat(" {0}", OtherInstallOptions); + + // custom install location must be last for NSIS + if (customInstallLocation) args.AppendFormat(" {0}", CustomInstallLocation); + + return args.ToString(); + } + + public virtual string build_uninstall_command_arguments() + { + return "{0} {1} {2} {3}".format_with(SilentUninstall, NoReboot, LogFile, OtherUninstallOptions); + } + } +} \ No newline at end of file diff --git a/src/chocolatey/infrastructure.app/domain/MsiInstaller.cs b/src/chocolatey/infrastructure.app/domain/MsiInstaller.cs index b082cde4e9..2a974517e7 100644 --- a/src/chocolatey/infrastructure.app/domain/MsiInstaller.cs +++ b/src/chocolatey/infrastructure.app/domain/MsiInstaller.cs @@ -15,7 +15,6 @@ namespace chocolatey.infrastructure.app.domain { - using System; using System.Collections.Generic; /// @@ -28,7 +27,7 @@ namespace chocolatey.infrastructure.app.domain /// http://www.advancedinstaller.com/user-guide/msiexec.html /// 1603 search for return value 3 http://blogs.msdn.com/b/astebner/archive/2005/08/01/446328.aspx /// - public class MsiInstaller : IInstaller + public class MsiInstaller : InstallerBase { public MsiInstaller() { @@ -44,37 +43,21 @@ public MsiInstaller() // http://msdn.microsoft.com/en-us/library/aa367559.aspx OtherInstallOptions = "ALLUSERS=1 DISABLEDESKTOPSHORTCUT=1 ADDDESKTOPICON=0 ADDSTARTMENU=0"; UninstallExecutable = "msiexec.exe"; + //todo: eventually will need this //SilentUninstall = "/qn /x{0}".format_with(InstallTokens.UNINSTALLER_LOCATION); SilentUninstall = "/qn"; OtherUninstallOptions = ""; - ValidExitCodes = new List {0, 3010}; + // https://msdn.microsoft.com/en-us/library/aa376931.aspx + // https://support.microsoft.com/en-us/kb/290158 + ValidInstallExitCodes = new List {0, 1641, 3010}; + // we allow unknown 1605/1614 b/c it may have already been uninstalled + // and that's okay + ValidUninstallExitCodes = new List {0, 1605, 1614, 1641, 3010}; } - public InstallerType InstallerType + public override InstallerType InstallerType { get { return InstallerType.Msi; } } - - public string InstallExecutable { get; private set; } - public string SilentInstall { get; private set; } - public string NoReboot { get; private set; } - public string LogFile { get; private set; } - public string OtherInstallOptions { get; private set; } - public string CustomInstallLocation { get; private set; } - public string Language { get; private set; } - public string UninstallExecutable { get; private set; } - public string SilentUninstall { get; private set; } - public string OtherUninstallOptions { get; private set; } - public IEnumerable ValidExitCodes { get; private set; } - - public string build_install_command_arguments() - { - throw new NotImplementedException(); - } - - public string build_uninstall_command_arguments() - { - return "{0} {1} {2}".format_with(SilentUninstall, NoReboot, OtherUninstallOptions); - } } } \ No newline at end of file diff --git a/src/chocolatey/infrastructure.app/domain/NsisInstaller.cs b/src/chocolatey/infrastructure.app/domain/NsisInstaller.cs index a0b4f7c05f..0d2e6e1a92 100644 --- a/src/chocolatey/infrastructure.app/domain/NsisInstaller.cs +++ b/src/chocolatey/infrastructure.app/domain/NsisInstaller.cs @@ -15,7 +15,6 @@ namespace chocolatey.infrastructure.app.domain { - using System; using System.Collections.Generic; /// @@ -26,7 +25,7 @@ namespace chocolatey.infrastructure.app.domain /// It is impossible to look at registry and determine a NSIS installer /// NSIS has no logging or language options. The command line usage is very little. /// - public class NsisInstaller : IInstaller + public class NsisInstaller : InstallerBase { public NsisInstaller() { @@ -34,40 +33,20 @@ public NsisInstaller() SilentInstall = "/S"; NoReboot = ""; LogFile = ""; + // must come last and contain no quotes, even if there are spaces CustomInstallLocation = "/D={0}".format_with(InstallTokens.CUSTOM_INSTALL_LOCATION); //must be last thing specified and no quotes Language = ""; OtherInstallOptions = ""; UninstallExecutable = "\"{0}\"".format_with(InstallTokens.UNINSTALLER_LOCATION); SilentUninstall = "/S"; OtherUninstallOptions = ""; - ValidExitCodes = new List {0}; + ValidInstallExitCodes = new List { 0 }; + ValidUninstallExitCodes = new List { 0 }; } - public InstallerType InstallerType + public override InstallerType InstallerType { get { return InstallerType.Nsis; } } - - public string InstallExecutable { get; private set; } - public string SilentInstall { get; private set; } - public string NoReboot { get; private set; } - public string LogFile { get; private set; } - public string CustomInstallLocation { get; private set; } - public string Language { get; private set; } - public string OtherInstallOptions { get; private set; } - public string UninstallExecutable { get; private set; } - public string SilentUninstall { get; private set; } - public string OtherUninstallOptions { get; private set; } - public IEnumerable ValidExitCodes { get; private set; } - - public string build_install_command_arguments() - { - throw new NotImplementedException(); - } - - public string build_uninstall_command_arguments() - { - return "{0} {1}".format_with(SilentUninstall, OtherInstallOptions); - } } } \ No newline at end of file