View Javadoc
1   package edu.jiangxin.apktoolbox.help.settings;
2   
3   import edu.jiangxin.apktoolbox.swing.extend.EasyChildTabbedPanel;
4   import edu.jiangxin.apktoolbox.utils.Constants;
5   import org.apache.commons.collections4.CollectionUtils;
6   import org.apache.commons.io.FileUtils;
7   
8   import javax.swing.*;
9   import java.io.File;
10  import java.io.IOException;
11  import java.io.Serial;
12  import java.net.URL;
13  import java.nio.file.Files;
14  import java.util.Collection;
15  
16  public class AddToStartupPanel extends EasyChildTabbedPanel {
17      @Serial
18      private static final long serialVersionUID = 1L;
19  
20      private static final String STARTUP_FILE;
21  
22      private JPanel optionPanel;
23  
24      static {
25          final String SEPARATOR = File.separator;
26          final String STARTUP_FOLDER;
27          if (System.getProperty("os.name").toLowerCase().contains("win")) {
28              STARTUP_FOLDER = System.getenv("APPDATA") + SEPARATOR + "Microsoft" + SEPARATOR + "Windows" + SEPARATOR + "Start Menu" + SEPARATOR + "Programs" + SEPARATOR + "Startup";
29          } else if (System.getProperty("os.name").toLowerCase().contains("mac")) {
30              STARTUP_FOLDER = System.getProperty("user.home") + SEPARATOR + "Library" + SEPARATOR + "LaunchAgents";
31          } else {
32              STARTUP_FOLDER = System.getProperty("user.home") + SEPARATOR + ".config" + SEPARATOR + "autostart";
33          }
34          STARTUP_FILE = STARTUP_FOLDER + SEPARATOR + "ApkToolBoxGUI.lnk";
35      }
36  
37      @Override
38      public void createUI() {
39          BoxLayout boxLayout = new BoxLayout(this, BoxLayout.Y_AXIS);
40          setLayout(boxLayout);
41  
42          createOptionPanel();
43          add(optionPanel);
44  
45          add(Box.createVerticalStrut(15 * Constants.DEFAULT_Y_BORDER));
46      }
47  
48      private void createOptionPanel() {
49          optionPanel = new JPanel();
50          optionPanel.setLayout(new BoxLayout(optionPanel, BoxLayout.X_AXIS));
51  
52          JLabel typeLabel = new JLabel("Add to startup:");
53          JCheckBox addToStartupCheckBox = new JCheckBox();
54          addToStartupCheckBox.setSelected(conf.getBoolean("add.to.startup", false));
55          addToStartupCheckBox.addActionListener(e -> {
56              conf.setProperty("add.to.startup", addToStartupCheckBox.isSelected());
57              if (addToStartupCheckBox.isSelected()) {
58                  addToStartup();
59              } else {
60                  FileUtils.deleteQuietly(new File(STARTUP_FILE));
61              }
62          });
63  
64          optionPanel.add(typeLabel);
65          optionPanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
66          optionPanel.add(addToStartupCheckBox);
67      }
68  
69      private void addToStartup() {
70          String executableFilePath = getExecutableFilePath();
71          if (executableFilePath == null) {
72              return;
73          }
74  
75          File shortcutFile = new File(STARTUP_FILE);
76  
77          if (!shortcutFile.exists()) {
78              try {
79                  createShortcut(executableFilePath);
80                  logger.info("create shortcut file successfully: {}", STARTUP_FILE);
81              } catch (IOException e) {
82                  logger.error("create shortcut file failed: {}", STARTUP_FILE, e);
83              }
84          }
85      }
86  
87      private String getExecutableFilePath() {
88          URL jarUrl = AddToStartupPanel.class.getProtectionDomain().getCodeSource().getLocation();
89          if (jarUrl == null) {
90              logger.error("jarUrl is null");
91              return null;
92          }
93          File jarFile = new File(jarUrl.getPath());
94          logger.info("jarFile: {}", jarFile.getAbsolutePath());
95          File grandpaFile = jarFile.getParentFile().getParentFile();
96          logger.info("parentFile: {}", grandpaFile.getAbsolutePath());
97          Collection<File> executableFiles = FileUtils.listFiles(grandpaFile, new String[]{"exe"}, false);
98          if (CollectionUtils.isEmpty(executableFiles)) {
99              logger.error("Can not find executable file");
100             return null;
101         }
102         if (executableFiles.size() > 1) {
103             logger.error("There are more than one executable file");
104             return null;
105         }
106         File executableFile = executableFiles.iterator().next();
107         logger.info("executableFile: {}", executableFile.getAbsolutePath());
108         return executableFile.getAbsolutePath();
109     }
110 
111     private static void createShortcut(String targetPath) throws IOException {
112         String vbsScript = """
113                 Set WshShell = CreateObject("WScript.Shell")
114                 Set Shortcut = WshShell.CreateShortcut("%s")
115                 Shortcut.TargetPath = "%s"
116                 Shortcut.Save
117                 """.formatted(STARTUP_FILE, targetPath);
118 
119         File tempVbs = Files.createTempFile("createShortcut", ".vbs").toFile();
120         Files.writeString(tempVbs.toPath(), vbsScript);
121 
122         ProcessBuilder builder = new ProcessBuilder("wscript", tempVbs.getAbsolutePath());
123         builder.start();
124         tempVbs.deleteOnExit();
125     }
126 }