按照"此磁带将在五秒钟内自毁。祝你好运,吉姆"...
一旦达到预设的使用时间或其他条件,应用程序是否可以删除自身(或其可执行包装形式)?
或者,可以使用哪些其他方法来使应用程序无用?
这里的目的是让测试版过期,邀请用户获得更新的版本。
这是可能的。 为了绕过 JAR 文件上的锁定,您的应用程序可能需要生成一个后台进程,该进程等到 JVM 退出后再删除内容。
但是,这不是防弹的。 有人可以安装应用程序,然后将安装的文件和目录设为只读,以便应用程序无法自行删除。 用户(或其管理员)通过操作系统的访问控制系统对创建和删除哪些文件拥有最终决定权。
如果您控制测试人员下载应用程序的位置,则可以使用自动构建系统(例如 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混合使用,以在反编译字节码并提供不包含该代码的替代实现时设置障碍,您可以分发代码的时间到期测试版。
可以将自动生成系统配置为自动将测试版上传到托管下载版本的服务器。
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脚本化安装系统的东西,它使您能够编写自己的安装/卸载程序应该会有所帮助。