private static void Remove(string[] packages) { foreach(string p in packages) { if(p == null || p.Length == 0) continue; Version instVersion = new Version("0.0.0"); string[] parts = p.Split('='); if(parts.Length > 1) { instVersion = GetProperVersion(parts[1]); } else { instVersion = null; } try { Product product = Library.GetProduct(parts[0]); if(product == null) { Console.Error.WriteLine("Could not find product " + parts[0]); continue; } int installnum = GetNumberofInstalledVersions(product.upgradeCode); if(installnum == 0) { Console.Error.WriteLine("ERROR: {0} is not installed", product.name); continue; } else if(installnum > 1 && instVersion == null) { Console.Error.WriteLine("ERROR: More than one version of {0} is installed. A version must be specified.", product.name); continue; } if(instVersion == null ? IsInstalled(product.name) : IsInstalled(product.name, instVersion, instVersion)) { Console.Write("Removing "+ product.name + "... "); WindowsInstaller.SetInternalUI(WindowsInstaller.MsiInstallUILevel.None, IntPtr.Zero); WindowsInstaller.MsiExternalUIHandler handler = new WindowsInstaller.MsiExternalUIHandler(UIHandler); WindowsInstaller.SetExternalUI( handler, WindowsInstaller.MsiInstallLogMode.Progress | WindowsInstaller.MsiInstallLogMode.Error | WindowsInstaller.MsiInstallLogMode.FatalExit, IntPtr.Zero); Guid productCode = GetVersionProductCode(product.upgradeCode, instVersion); uint ret = WindowsInstaller.ConfigureProduct(productCode, WindowsInstaller.MsiInstallLevel.Default, WindowsInstaller.MsiInstallState.Absent, "REBOOT=R"); GC.KeepAlive(handler); Console.Write("\x08"); Console.WriteLine(getErrorMessage(ret)); } else Console.Error.WriteLine("ERROR: The specified version of {0} is not installed", product.name); } catch(WiptException e) { Console.WriteLine(e.Message); } } }
private static bool Install(string p, bool ignoretransforms, bool ignorepatches, bool peruser, string targetdir, string installlevel, bool reinstall) { try { if(p == "") return true; Version instVersion = null; string[] parts = p.Split('='); if(parts.Length > 1) { instVersion = GetProperVersion(parts[1]); } Product product = Library.GetProduct(parts[0]); if(product == null) { Console.Error.WriteLine("No such product " + parts[0]); return false; } bool alreadyInstalled = (instVersion == null ? IsInstalled(product.name) : IsInstalled(product.name, instVersion, instVersion)); if(alreadyInstalled && !reinstall) { Console.Error.WriteLine("{0} is already installed", product.name); return true; } else if(!alreadyInstalled && reinstall) { Console.Error.WriteLine("{0} is not installed", product.name); return false; } if(instVersion == null) { if(product.stableVersion == null) { Console.Error.WriteLine("{0} has no StableVersion specified. You must supply a version to install.", product.name); } else instVersion = product.stableVersion; } string Url = ""; string properties = ""; Patch[] patches = null; if(targetdir == "") { string temp; if((temp = WiptConfig.GetTargetPath()) != null) { targetdir = temp; } } if(!ignoretransforms && product.transforms.Length > 0) { properties += "TRANSFORMS="; foreach(Transform transform in product.transforms) { if((transform.minVersion == null || instVersion >= transform.minVersion) && (transform.maxVersion == null || instVersion <= transform.maxVersion)) { Url = transform.Url; if(Url.StartsWith("file://")) { // The Windows Installer system does not support file: URLs. Don't know why. Url = Url.Substring(7); Url = Url.Replace("/", "\\"); // Windows appears to support either two or four slashes on UNC paths, so we // support both. if(Url[1] != ':' && Url[1] != '\\') Url = "\\\\" + Url; } properties += Url + ";"; } } Url = ""; properties += " "; } Guid productCode = Guid.Empty; patches = product.patches; foreach(Package package in product.packages) { if(package.version == instVersion) { Url = package.Url; productCode = package.productCode; break; } } if(Url == "") { Console.Error.WriteLine("No package listed for specified version of " + product.name + ". Contact the repository maintainer."); return false; } else if(Url.StartsWith("file://")) { // The Windows Installer system does not support file: URLs. Don't know why. Url = Url.Substring(7); Url = Url.Replace("/", "\\"); // Windows appears to support either two or four slashes on UNC paths, so we // support both. if(Url[1] != ':' && Url[1] != '\\') Url = "\\\\" + Url; } WindowsInstaller.MsiInstallState state = WindowsInstaller.QueryProductState(productCode); if(reinstall || (state != WindowsInstaller.MsiInstallState.Removed && state != WindowsInstaller.MsiInstallState.Absent && state != WindowsInstaller.MsiInstallState.Unknown)) { // minor upgrade properties += "REINSTALL=ALL REINSTALLMODE=vomus "; } if(installlevel != null && installlevel != "") properties += "INSTALLLEVEL=" + installlevel + " "; if(targetdir == "") { targetdir = "\"" + Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "\""; Console.Error.WriteLine("Warning: no TARGETDIR specified. Defaulting to " + targetdir); } properties += "TARGETDIR=" + targetdir + " REBOOT=R "; if(!peruser) { properties += "ALLUSERS=1 "; } Console.Write("Installing "+ product.name + "... "); WindowsInstaller.SetInternalUI(WindowsInstaller.MsiInstallUILevel.None, IntPtr.Zero); WindowsInstaller.MsiExternalUIHandler handler = new WindowsInstaller.MsiExternalUIHandler(UIHandler); WindowsInstaller.SetExternalUI( handler, WindowsInstaller.MsiInstallLogMode.Progress | WindowsInstaller.MsiInstallLogMode.Error | WindowsInstaller.MsiInstallLogMode.FatalExit, IntPtr.Zero); uint ret; ret = WindowsInstaller.InstallProduct(Url, properties); GC.KeepAlive(handler); Console.Write("\x08"); Console.WriteLine(getErrorMessage(ret)); // Hackish way to prevent reapplication of patches foreach(Patch x in patches) { if(IsPatchApplied(x, productCode)) { x.productCodes = new Guid[1]{Guid.Empty}; } } if(ret != 0 && ret != 3010) return false; if(!(ignorepatches || ApplyPatches(patches, productCode))) return false; return true; } catch(WiptException e) { Console.Error.WriteLine(e.Message); return false; } }