X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~yarrgweb/git?a=blobdiff_plain;f=src%2Fcom%2Ftedpearson%2Fypp%2Fmarket%2FInstaller.java;fp=src%2Fcom%2Ftedpearson%2Fypp%2Fmarket%2FInstaller.java;h=a7621b823b4befa927313e5d48cfcf5de178c390;hb=3cff51a7f2bf5a5d9b78482f408da1b70037994c;hp=0000000000000000000000000000000000000000;hpb=afbe2cc2cc040e051ee1f55be352db0bf319a8e1;p=jarrg-owen.git diff --git a/src/com/tedpearson/ypp/market/Installer.java b/src/com/tedpearson/ypp/market/Installer.java new file mode 100644 index 0000000..a7621b8 --- /dev/null +++ b/src/com/tedpearson/ypp/market/Installer.java @@ -0,0 +1,345 @@ +package com.tedpearson.ypp.market; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import javax.swing.border.*; +import java.io.*; +import com.tedpearson.util.update.*; +import java.util.Properties; +import java.net.URLDecoder; + +/* + allow adding islands/oceans + implement uploads to YAARG +*/ + +/** +* An Installer for PCTB Java Client. +*/ +public class Installer extends JFrame { + public final static int VERSION = 8; + private JLabel label; + private JProgressBar progress; + private JButton install, uninstall; + private static String os = System.getProperty("os.name"); + private static String home = System.getProperty("java.home"); + private static String user_home = System.getProperty("user.home"); + private boolean installed = false; + private boolean uninstalled = false; + private static PrintWriter pw; + + public static void debug(String str) { + try { + pw.println(str); + pw.flush(); + }catch(Exception e) { + + } + } + + public static void main(String[] args) { + /* + try{ + pw = new PrintWriter("C:/Users/Public/ERRORS"); + }catch(Exception e) { + + } + */ + new Installer(args); + } + + /** + * Checks if we have permission to write to the Java Home folder + * that runs YPP. Pops up an error message and exits if we don't have access, + * or on Mac OS X, re-runs the installer using applescript to authenticate. + */ + private void checkPermission(String[] args) { + File a11y = null; + a11y = new File(getJavaHome(),"lib"); + if(os.equals("Mac OS X")) { + if(!a11y.canWrite()) { + JOptionPane.showMessageDialog(null,"Please authenticate as an Administrator, when prompted, to continue installation."); + try { + String installer = URLDecoder.decode(getClass().getProtectionDomain().getCodeSource().getLocation() + .getPath(), "URT-8"); + Runtime.getRuntime().exec(new String[]{"osascript","-e","do shell script \"java -jar " + + installer + "\" with administrator privileges"}); + } catch(Exception e) { + e.printStackTrace(); + } + System.exit(0); + } + } else { + // clean up after myself + if(os.contains("Vista")) { + File tempDir = new File(System.getProperty("java.io.tmpdir")); + for(File f : tempDir.listFiles()) { + if(f.getName().startsWith("PCTB-lib")) { + for(File g : f.listFiles()) { + g.delete(); + } + f.delete(); + } + } + } + // first check for YPP java + boolean canWrite = true; + File test = new File(a11y, "test_pctb"); + try { + test.createNewFile(); + test.delete(); + } catch(IOException e) { + canWrite = false; + } + if(!canWrite || !a11y.canWrite()) { + if(os.contains("Vista")) { + if(args.length == 1 && args[0].equals("--elevate")) { + JOptionPane.showMessageDialog(null,"Please run this installer while logged in as an Administrator."); + System.exit(0); + } + try { + String installer = URLDecoder.decode(getClass().getProtectionDomain().getCodeSource().getLocation() + .getPath(), "UTF-8").replaceFirst("/",""); + ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/C", "elevate javaw -jar \"" + installer + + "\" --elevate"); + // create temp lib directory + File temp = File.createTempFile("PCTB-lib",null); + temp.delete(); + temp.mkdir(); + File elevate = new File(temp, "elevate.cmd"); + OutputStream out = new FileOutputStream(elevate); + InputStream in = getClass().getResourceAsStream("/lib/elevate.cmd"); + Updater.copyFile(in, out); + + elevate = new File(temp, "elevate.vbs"); + out = new FileOutputStream(elevate); + in = getClass().getResourceAsStream("/lib/elevate.vbs"); + Updater.copyFile(in, out); + + pb.directory(temp); + Process p = pb.start(); + } catch(Exception e) { + e.printStackTrace(); + } + System.exit(0); + } else { + JOptionPane.showMessageDialog(null,"Please run this installer while logged in as an Administrator."); + System.exit(0); + } + } + } + } + + /** + * Create the installer GUI + */ + public Installer(String[] args) { + super("PCTB Installer"); + + Updater.getUpdater().checkAndUpdate(null, "http://tedpearson.com/market/version", + "the PCTB Uploader client", VERSION, true, + getClass().getProtectionDomain().getCodeSource().getLocation().getPath()); + + // gui: simple window with status area and progress bar + checkPermission(args); + label = new JLabel("Ready to install!"); + add(label,BorderLayout.NORTH); + progress = new JProgressBar(); + progress.setBorder(new EmptyBorder(10,0,10,0)); + add(progress,BorderLayout.CENTER); + String buttonText = "Install"; + install = new JButton(buttonText); + JPanel buttons = new JPanel(); + add(buttons,BorderLayout.SOUTH); + install.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if(installed) { + System.exit(0); + } + try { + install.setEnabled(false); + uninstall.setEnabled(false); + install(); + } catch(IOException err) { + err.printStackTrace(); + JOptionPane.showMessageDialog(Installer.this, "Error during installation."); + setButtonStatus(false,false); + label.setText("Install failed!"); + } + } + }); + uninstall = new JButton("Uninstall"); + buttons.add(uninstall); + buttons.add(install); + uninstall.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if(uninstalled) { + System.exit(0); + } + try { + install.setEnabled(false); + uninstall.setEnabled(false); + uninstall(); + } catch(IOException err) { + err.printStackTrace(); + JOptionPane.showMessageDialog(Installer.this, "Error during installation."); + setButtonStatus(false,false); + label.setText("Uninstall failed!"); + } + } + }); + getRootPane().setBorder(new EmptyBorder(10,10,10,10)); + getRootPane().setDefaultButton(install); + pack(); + setSize(300,getHeight()); + setLocationRelativeTo(null); + setDefaultCloseOperation(EXIT_ON_CLOSE); + setVisible(true); + } + + /** + * Uninstalls the client. Throws an IOException ir errors occur. + * (removes the PCTB class from assistive tech, deletes the jar) + */ + private void uninstall() throws IOException { + label.setText("Uninstalling..."); + progress.setIndeterminate(true); + // remove from assistive tech + File java_home = getJavaHome(); + File a11y = new File(java_home,"lib/accessibility.properties"); + if(a11y.exists()) { + Properties p = new Properties(); + p.load(new FileInputStream(a11y)); + String tech = p.getProperty("assistive_technologies"); + tech = tech.replace("com.tedpearson.ypp.market.MarketUploader", ""); + p.setProperty("assistive_technologies", tech); + p.store(new FileOutputStream(a11y),"Last Modified by PCTB-Installer"); + } + // remove jar + File jar = new File(java_home, "lib/ext/PCTB-Uploader.jar"); + jar.delete(); + setButtonStatus(false,true); + } + + /** + * Utility method to find the Java Home folder that runs YPP. On Windows, it could be + * inside the YPP folder. + */ + private File getJavaHome() { + File java_home = new File(home); + if(os.contains("Windows")) { + File defaultLocation = null; + // check for javavm inside YPP folder, otherwise default location + if(os.contains("Vista")) { + String user = System.getProperty("user.name"); + defaultLocation = new File("C:\\Users\\" + user + "\\AppData\\Roaming\\Three Rings Design\\Puzzle Pirates\\"); + } else if(os.contains("XP")) { + defaultLocation = new File("C:\\Program Files\\Three Rings Design\\Puzzle Pirates\\"); + } + if(defaultLocation != null && defaultLocation.exists()) { + File java_vm = new File(defaultLocation, "java_vm"); + if(java_vm.exists()) { + // this is where we want to install instead + java_home = new File(defaultLocation, "java_vm"); + } + } + } + return java_home; + } + + /** + * Installs the client. + */ + private void install() throws IOException { + label.setText("Installing..."); + progress.setIndeterminate(true); + File java_home = getJavaHome(); + File controlPanel = new File(user_home); + JFileChooser chooser = new JFileChooser(controlPanel); + chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + chooser.setDialogTitle("Choose location for Control Panel"); + chooser.setApproveButtonText("Install Control Panel here"); + int state = chooser.showOpenDialog(this); + if(state == JFileChooser.APPROVE_OPTION) { + controlPanel = chooser.getSelectedFile(); + } else { + setButtonStatus(false,false); + label.setText("Install failed!"); + return; + } + InputStream in = getClass().getResourceAsStream("/PCTB-ControlPanel.jar"); + File newFile = new File(controlPanel, "PCTB-ControlPanel.jar"); + newFile.createNewFile(); + OutputStream out = new FileOutputStream(newFile); + Updater.copyFile(in, out); + String search = "assistive_technologies"; + String value = "com.tedpearson.ypp.market.MarketUploader"; + File a11y = new File(java_home,"lib/accessibility.properties"); + boolean skipA11y = false; + Properties p = new Properties(); + if(a11y.exists()) { + // if already contains our modification, ignore + // else add our modification + p.load(new FileInputStream(a11y)); + String tech = p.getProperty(search); + if(tech == null || tech.trim().equals("")) { + // add it! + p.setProperty(search, value); + p.store(new FileOutputStream(a11y),"Last Modified by PCTB-Installer"); + } else if(!tech.contains(value)) { + p.setProperty(search, tech+","+value); + p.store(new FileOutputStream(a11y),"Last Modified by PCTB-Installer"); + } + } else { + // create file with our modification + a11y.createNewFile(); + p.setProperty(search, value); + p.store(new FileOutputStream(a11y),"Last Modified by PCTB-Installer"); + } + + // install program + // copy jar from resource to new file in ext + //String installer = getClass().getProtectionDomain().getCodeSource().getLocation() + // .getPath().replaceAll("%20"," "); + //new FileInputStream(installer); + in = getClass().getResourceAsStream("/PCTB-Uploader.jar"); + newFile = new File(java_home, "lib/ext/PCTB-Uploader.jar"); + newFile.createNewFile(); + out = new FileOutputStream(newFile); + Updater.copyFile(in, out); + JOptionPane.showMessageDialog(this, "Install successful!\n\nWhen you open a new YPP client, you'll see\n" + + "the upload client window alongside YPP.\n\n" + + "To stop the window from appearing, use\n" + + "the Control Panel to disable it, or uninstall.", "Success!", JOptionPane.INFORMATION_MESSAGE); + setButtonStatus(true,false); + } + + /** + * Cleanup after an install, uninstall, or error. Buttons, statuses, and such + */ + private void setButtonStatus(boolean installQ, boolean uninstallQ) { + progress.setIndeterminate(false); + progress.setValue(100); + install.setEnabled(true); + uninstall.setEnabled(true); + String q = "Quit"; + if(installQ) { + install.setText(q); + installed = true; + label.setText("Install complete!"); + } else { + install.setText("Install"); + installed = false; + } + + if(uninstallQ) { + uninstall.setText(q); + uninstalled = true; + label.setText("Uninstall successful."); + } else { + uninstall.setText("Uninstall"); + uninstalled = false; + } + } +} \ No newline at end of file