自毁应用程序

沿着“这条磁带将在五秒内自毁。祝你好运,吉姆” ……

一旦达到预设的使用时间或其他条件,应用程序是否可以删除自身(或它的可执行包装forms)?

或者,可以使用哪些其他方法使应用程序无用?

这里的目标是让测试版到期,邀请用户获得更新版本。

有可能的。 为了解决JAR文件上的锁定问题,您的应用程序可能需要生成一个后台进程,该进程在删除内容之前等待JVM退出。

但是,这不是防弹的。 有人可以安装应用程序,然后将安装的文件和目录设置为只读,这样您的应用程序就无法自行删除。 通过OS’es访问控制系统的用户(或他们的管理员)对创建和删除的文件有最终决定权。

如果您控制测试人员下载您的应用程序的位置,您可以使用自动构建系统(例如Jenkins ),您可以每晚创建一个具有硬编码到期日期的新测试版本:

private static final Date EXPIRY_DATE = <90 days in the future from build date>; 

上述日期由构建过程自动插入

 if (EXPIRY_DATE.before(new Date()) { System.out.println("Get a new beta version, please"); System.exit(1); } 

将其与签名和密封的jar子混合,以阻止反编译字节码的方式,并提供不包含该代码的替代实现,您可以分发代码的时间到期beta。

自动构建系统可以配置为自动将beta版本上载到托管下载版本的服务器。

由于Windows在JAR文件运行时将其锁定,因此您无法从自己的Java代码中删除它,因此您需要Batch文件:

 private static void selfDestructWindowsJARFile() throws Exception { String resourceName = "self-destruct.bat"; File scriptFile = File.createTempFile(FilenameUtils.getBaseName(resourceName), "." + FilenameUtils.getExtension(resourceName)); try (FileWriter fileWriter = new FileWriter(scriptFile); PrintWriter printWriter = new PrintWriter(fileWriter)) { printWriter.println("taskkill /F /IM \"java.exe\""); printWriter.println("DEL /F \"" + ProgramDirectoryUtilities.getCurrentJARFilePath() + "\""); printWriter.println("start /b \"\" cmd /c del \"%~f0\"&exit /b"); } Desktop.getDesktop().open(scriptFile); } public static void selfDestructJARFile() throws Exception { if (SystemUtils.IS_OS_WINDOWS) { selfDestructWindowsJARFile(); } else { // Unix does not lock the JAR file so we can just delete it File directoryFilePath = ProgramDirectoryUtilities.getCurrentJARFilePath(); Files.delete(directoryFilePath.toPath()); } System.exit(0); } 

ProgramDirectoryUtilities类:

 public class ProgramDirectoryUtilities { private static String getJarName() { return new File(ProgramDirectoryUtilities.class.getProtectionDomain() .getCodeSource() .getLocation() .getPath()) .getName(); } public static boolean isRunningFromJAR() { String jarName = getJarName(); return jarName.contains(".jar"); } public static String getProgramDirectory() { if (isRunningFromJAR()) { return getCurrentJARDirectory(); } else { return getCurrentProjectDirectory(); } } private static String getCurrentProjectDirectory() { return new File("").getAbsolutePath(); } public static String getCurrentJARDirectory() { try { return getCurrentJARFilePath().getParent(); } catch (URISyntaxException exception) { exception.printStackTrace(); } throw new IllegalStateException("Unexpected null JAR path"); } public static File getCurrentJARFilePath() throws URISyntaxException { return new File(ProgramDirectoryUtilities.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()); } } 

解决方案受此问题启发。


这是一个更好的Windows方法:

 private static void selfDestructWindowsJARFile() throws Exception { String currentJARFilePath = ProgramDirectoryUtilities.getCurrentJARFilePath().toString(); Runtime runtime = Runtime.getRuntime(); runtime.exec("cmd /c ping localhost -n 2 > nul && del \"" + currentJARFilePath + "\""); } 

这是原始答案。

我猜这很有可能。 也许你可以删除这样的jar,并确保应用程序消失,因为你有权利。

 File jar = new File(".\\app.jar"); jar.deleteOnExit(); System.exit(0); 

还使用Nullsoft Scriptable Install System之类的东西,它可以帮助您编写自己的安装/卸载程序。