1 /* 2 * Copyright (c) 2014, 2016 Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 */ 5 package com.oracle.appbundlers.utils.installers; 6 7 import static com.oracle.appbundlers.utils.Config.CONFIG_INSTANCE; 8 import static com.oracle.appbundlers.utils.Utils.getProgramFilesDirWindows; 9 import static java.nio.file.Files.exists; 10 import static org.testng.Assert.assertTrue; 11 import static org.testng.Assert.fail; 12 13 import java.io.IOException; 14 import java.nio.charset.StandardCharsets; 15 import java.nio.file.Files; 16 import java.nio.file.Path; 17 import java.nio.file.Paths; 18 import java.nio.file.StandardCopyOption; 19 import java.util.List; 20 import java.util.Optional; 21 import java.util.concurrent.ExecutionException; 22 import java.util.logging.Level; 23 import java.util.logging.Logger; 24 25 import com.oracle.appbundlers.utils.AppWrapper; 26 import com.oracle.appbundlers.utils.BundlerUtils; 27 import com.oracle.appbundlers.utils.Config; 28 import com.oracle.appbundlers.utils.ProcessOutput; 29 import com.oracle.appbundlers.utils.Utils; 30 import com.oracle.appbundlers.utils.windows.Registry; 31 32 /** 33 * 34 * @author Dmitry Ginzburg <dmitry.x.ginzburg@oracle.com> 35 * @author Dmitry Zinkevich <dmitry.zinkevich@oracle.com> 36 */ 37 public class WinExeBundlerUtils extends WinAbstractBundlerUtils { 38 39 private static final Logger LOG = Logger 40 .getLogger(WinExeBundlerUtils.class.getName()); 41 42 { 43 verificators.put(SHORTCUT_HINT, getShortcutHintVerificator()); 44 45 verificators.put(MENU_HINT, getMenuGroupVerificator()); 46 verificators.put(SERVICE_HINT, getServiceHintVerificator()); 47 verificators.put(START_ON_INSTALL, getStartOnInstallVerificator()); 48 verificators.put(RUN_AT_STARTUP, getRunAtStartupVerificator()); 49 verificators.put(VENDOR, getMenuGroupVerificator()); 50 verificators.put(VERSION, (version, app, appName) -> { 51 Path config = getInstalledAppRootLocation(app, appName) 52 .resolve("app/" + appName + ".cfg"); 53 try { 54 assertTrue( 55 Utils.checkFileContains(config, 56 "app.version=" + version), 57 "[Version info not found]"); 58 } catch (IOException ex) { 59 fail("[Unable to read package.cfg]"); 60 } 61 }); 62 63 verificators.put(SYSTEM_WIDE, getSystemWideOptionVerificator()); 64 verificators.put(EXE_SYSTEM_WIDE, getSystemWideOptionVerificator()); 65 verificators.put(MENU_GROUP, getMenuGroupVerificator()); 66 verificators.put(WIN_USER_FILE_ASSOCIATIONS, 67 getUserFileAssociationVerificator()); 68 verificators.put(WIN_SYSTEM_WIDE_FILE_ASSOCIATIONS, 69 getFileAssociationVerificator()); 70 verificators.put(TITLE, (val, app, appName) -> { 71 Optional<String> optKey = Registry.findAppRegistryKey(appName); 72 assertTrue(optKey.isPresent(), 73 "[Registry info not found for " + appName + "]"); 74 75 Optional<List<String>> optContent = Registry.queryKey(optKey.get()); 76 optContent.ifPresent(System.out::println); 77 final String expectedText = val.toString(); 78 79 Optional<String> comment = optContent.map(content -> { 80 return content.parallelStream().map(String::trim) 81 .filter(s -> s.startsWith("Comments") 82 && s.endsWith(expectedText)) 83 .findFirst(); 84 }).orElseGet(() -> { 85 return Optional.empty(); 86 }); 87 88 assertTrue(comment.isPresent(), 89 "[Comments are not set in registry for " + appName + "]"); 90 }); 91 92 verificators.put(COPYRIGHT, (copyright, app, appName) -> { 93 Path installer = app.getWorkDir().resolve(appName + "-1.0.exe"); 94 assertTrue(exists(installer), 95 "[" + installer + " does not exists]"); 96 97 try { 98 Path temp = Files.createTempDirectory("SQE"); 99 Path tmpInstaller = Files.copy(installer, 100 temp.resolve("installer.exe"), 101 StandardCopyOption.COPY_ATTRIBUTES); 102 103 String content = new String( 104 Files.readAllBytes( 105 Config.CONFIG_INSTANCE.getResourcePath() 106 .resolve("getExeCopyright.vbs")), 107 StandardCharsets.UTF_8); 108 109 Path script = Files.createFile(temp.resolve("script.vbs")); 110 Files.write(script, 111 content.replace("__FILE_NAME__", 112 tmpInstaller.getFileName().toString()) 113 .getBytes()); 114 115 ProcessOutput output = Utils.runCommand( 116 new String[] { "cscript", script.toString() }, true, 117 CONFIG_INSTANCE.getRunTimeout()); 118 119 assertTrue( 120 output.getOutputStream().parallelStream() 121 .map(String::trim).anyMatch( 122 s -> s.contains(copyright.toString())), 123 "[Copyright wasn't stored in " + installer + "]"); 124 125 } catch (IOException | ExecutionException ex) { 126 fail("[Unable to query " + installer + " due to " 127 + ex.getMessage() + "]"); 128 } 129 }); 130 131 verificators.put(DESCRIPTION, getServiceDescriptionVerificator()); 132 } 133 134 public WinExeBundlerUtils() { 135 super(BundleType.INSTALLER, BundlerUtils.EXE); 136 } 137 138 @Override 139 public String install(AppWrapper app, String applicationTitle) 140 throws IOException { 141 String exePath = findByExtension(app.getBundlesDir(), "exe", 142 ROOT_DIRECTORY_DEPTH).toString(); 143 try { 144 LOG.log(Level.INFO, "Installing {0}.", exePath); 145 String[] cmd = new String[] { exePath, "/VERYSILENT" }; 146 Utils.runCommand(cmd, true, CONFIG_INSTANCE.getInstallTimeout()); 147 LOG.info("Installation done."); 148 } catch (ExecutionException e) { 149 throw new IOException(e); 150 } 151 return getInstalledExecutableLocation(app, applicationTitle).toString(); 152 } 153 154 @Override 155 public void uninstall(AppWrapper app, String appName) throws IOException { 156 try { 157 final Path exePath = Paths.get(appName, "unins000.exe"); 158 159 Path uninstaller = Paths.get(System.getenv("LOCALAPPDATA")) 160 .resolve(exePath); 161 if (!exists(uninstaller)) { 162 uninstaller = Paths.get(getProgramFilesDirWindows()) 163 .resolve(exePath); 164 } 165 if (!exists(uninstaller)) { 166 LOG.warning("Can't find uninstaller."); 167 return; 168 } 169 LOG.log(Level.INFO, "Using uninstaller: {0}", uninstaller); 170 LOG.log(Level.INFO, "Uninstalling {0}", appName); 171 String[] cmd = new String[] { uninstaller.toString(), 172 "/VERYSILENT" }; 173 Utils.runCommand(cmd, true, CONFIG_INSTANCE.getInstallTimeout()); 174 LOG.info("Uninstallation done."); 175 } catch (ExecutionException e) { 176 throw new IOException(e); 177 } 178 } 179 180 @Override 181 public Path getInstalledAppRootLocation(AppWrapper app, String appName) { 182 Path installPath = Paths.get(System.getenv("LOCALAPPDATA"), appName); 183 if (!Files.exists(installPath)) { 184 installPath = Paths.get(getProgramFilesDirWindows(), appName); 185 } 186 187 assertTrue(Files.exists(installPath), 188 "[" + installPath + " not found]"); 189 return installPath; 190 } 191 192 @Override 193 public void manualInstall(AppWrapper app) throws IOException { 194 String exePath = findByExtension(app.getBundlesDir(), "exe", 195 ROOT_DIRECTORY_DEPTH).toString(); 196 try { 197 LOG.log(Level.INFO, "Running installer: {0}", exePath); 198 Utils.runCommand(new String[] { exePath }, true, 199 CONFIG_INSTANCE.getInstallTimeout()); 200 } catch (ExecutionException e) { 201 throw new IOException(e); 202 } 203 } 204 }