Я придумал решение, есть некоторые вспомогательные классы вызовов, но в целом я думаю, ясно, что сделано:
Ключом часть:
Runtime.getRuntime(). exec ("cmd/c start \" процесс обновления \ "" + batFile);
, где командный файл запускается в независимом процессе, сам пакетный файл выполняет все операции копирования.
/**
* update the client installation, downloading update from server
*
* @return true if the update was successful
* @throws InvocationTargetException
* @throws InterruptedException
*/
protected boolean updateClient() throws InvocationTargetException, InterruptedException {
final File installDirectory = PathUtil.convertToFile(Platform.getInstallLocation().getURL());
if (!installDirectory.canWrite()) {
MessageDialog.openError(Display.getDefault().getActiveShell(), "Keine Schreibrechte",
"Keine Schreibrechte auf dem Installationsverzeichnis, Update kann nicht durchgeführt werden. Bitte benachrichtigen Sie einen Administrator.");
return false;
}
ProgressMonitorDialog dialog = new ProgressMonitorDialog(Display.getDefault().getActiveShell());
dialog.run(false, false, new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
try {
monitor.setTaskName("Update wird heruntergeladen");
File updateDirectory = Files.createTempDirectory("update_").toFile(); //$NON-NLS-1$
File outputDirectory = new File(updateDirectory, "PackageClient"); //$NON-NLS-1$
String arch = System.getProperty("osgi.arch"); //$NON-NLS-1$
HttpURLConnection connection = ConnectionUtil.openConnection("update/PackageClient_" + arch + ".zip"); //$NON-NLS-1$ //$NON-NLS-2$
logger.info("download update from {}", connection.getURL()); //$NON-NLS-1$
logger.info("unpack update to {}", outputDirectory); //$NON-NLS-1$
InputStream in = connection.getInputStream();
ZipUtil.unzipToDirectory(outputDirectory, in, monitor);
in.close();
// write batch file for later execution, since not able to update running application and JRE
String launcher = System.getProperty("eclipse.launcher"); //$NON-NLS-1$
File batFile = new File(updateDirectory, "update.bat"); //$NON-NLS-1$
// create batch file which will create backup, delete original installation, copy update and start application
String batchContent = String.format(
"xcopy \"%1$s\" \"%2$s\\backup\" /i /s /h /e /y\r\n" //$NON-NLS-1$
+ "FOR /D %%%%p IN (\"%1$s\\*.*\") DO rmdir \"%%%%p\" /s /q\r\ndel /q \"%1$s\\*.*\"\r\n" //$NON-NLS-1$
+ "xcopy \"%3$s\" \"%1$s\" /i /s /h /e /y\r\ncd \"%1$s\"\r\n" + "start \"\" \"%4$s\"\r\n" //$NON-NLS-1$ //$NON-NLS-2$
+ "start /MIN \"\" cmd /c rmdir \"%2$s\" /s /q exit\r\nexit", //$NON-NLS-1$
installDirectory, updateDirectory, outputDirectory, launcher);
FileUtil.writeFile(batFile, batchContent);
logger.info("launching update batch file {}", batFile); //$NON-NLS-1$
// start update batch file in independent process
Runtime.getRuntime().exec("cmd /c start \"update process\" " + batFile); //$NON-NLS-1$
} catch (Exception e) {
throw new InvocationTargetException(e);
}
}
});
return dialog.getReturnCode() == Window.OK;
}
Вот пример командного файла, который создается:
xcopy "D:\temp\test\eclipse" "D:\temp\fdo\update_3081617184889033760\backup" /i /s /h /e /y
FOR /D %%p IN ("D:\temp\test\eclipse\*.*") DO rmdir "%%p" /s /q
del /q "D:\temp\test\eclipse\*.*"
xcopy "D:\temp\fdo\update_3081617184889033760\PackageClient" "D:\temp\test\eclipse" /i /s /h /e /y
cd "D:\temp\test\eclipse"
start "" "D:\temp\test\eclipse\Application.exe"
start /MIN "" cmd /c rmdir "D:\temp\fdo\update_3081617184889033760" /s /q exit
exit
Вы говорите, что вы не хотите, но очевидный ответ заключается в использовании p2. Какова ваша причина избежать этого? –
Для того, что я нашел в Интернете, p2 также не может обновлять JRE: https://bugs.eclipse.org/bugs/show_bug.cgi?id=300812 –
Комментарий к https: //bugs.eclipse. org/bugs/show_bug.cgi? id = 300812 # c25 говорит, что вы можете использовать touchpoint для ссылки на другую папку, содержащую обновленную JRE. Но это оставляет старый (и), лежащий вокруг. –