2

I made a way to make my program, written in Java, update itself. The final JAR is wrapped in a EXE file, through Launch4j tool. You need to know this piece of code:

System.getProperty("java.class.path").replaceAll("\\;\\.$", "")

gives me the actual path of the EXE. I tested it and it seems to be always working. This is important for the problem.

Now, basically the program pings a webpage and reads a series of values, which one of them is the latest version of the program. If it's greater, the program notifies the user for the update. So, the program downloads the remote data (updated EXE file) and stores them in the current running EXE file, whose filename is obtained through the method explained above. It works, but here comes the problem.

I could simply launch the downloaded EXE file and System.exit the current one, but I cannot do this, because my program works with smart cards: if two or more programs use the same smart cards, the new one won't work (I don't know why, I even restart the provider each time, but this is another story). So I prevent users from starting multiple istances of the program.

(My customers are not so smart to manually open the program each time they need it, so I needed to override the close button to make it stay in traybar, and wake up everytime it is needed. I even make it starts when Windows boots up).

So I have to close the current instance of the program, and launch again. How I do this? I write a batch file which will basically look like this:

@echo off
taskkill /f /pid <pid of the exe program>
ping 127.0.0.1 -n 3 (this is a way to wait. I will eventually lower the waiting)
C:\Users\Mark\Desktop\program.exe (string generated by the method above. It should launch the program)
exit

Once written to disk, I execute it through Java:

Runtime.getRuntime().exec("cmd /c start " + batchFile.toString());

"batchFile" variable is a File object. The problem is that the new downloaded program is not launched. A console window appears, shows the result of "taskkill" and "ping" (I will eventually mute them), but the program does not start. If I launch the batch file manually, it does. Why? I really don't understand this behaviour. Do you have any advice?

Thanks in advance!

TL;DR version: The batch file executed by my Java program does not start the exe file written in it. Why?

FonzTech
  • 408
  • 1
  • 5
  • 13
  • 1
    Have you tried `start` or `call` in front of the path to the exe in the batch-file? – geisterfurz007 Sep 28 '17 at 06:27
  • Thanks for your comment. I tried "start" and "call", but none of them works when called by Java! – FonzTech Sep 28 '17 at 14:01
  • 1
    Maybe you can find the problem by reading the output of the executed batch-file when it is run from within Java with [this answer](https://stackoverflow.com/a/5711150/6707985) ? The command-line should output the reason why it is not executing the program and you should be able to read it that way. – geisterfurz007 Sep 28 '17 at 14:09
  • If I "echo %ERRORLEVEL%" right after the EXE file line, it gives me 2, so the specified file is not found? Why? The file exists! Do I must specify something in the Java call? – FonzTech Sep 28 '17 at 14:11
  • 1
    Not that I know. Does the program to launch or the path to it contain spaces? – geisterfurz007 Sep 28 '17 at 14:11
  • No, it does not contain spaces. The strange thing is that If I double click the batch file, it works... It doesn't when called by Java! – FonzTech Sep 28 '17 at 14:14
  • If I try to start everything which is in the PATH variable (such as notepad.exe) it works. It doesn't when custom paths are specified... I don't know why. I'm starting to think that it's a security feature! – FonzTech Sep 28 '17 at 14:28
  • Again did you try to print the output of the batch-file if run from Java? – geisterfurz007 Sep 28 '17 at 14:50
  • I can't print the output, because I taskkill the current process. Anyway, the problem is clear: when I call my EXE file, it gives an error code 2, which means the file is not found... This is the problem – FonzTech Sep 28 '17 at 14:53

1 Answers1

0

I have the feeling you are trying to overwrite an executable file (EXE) that is currently running. AFAIK Windows locks such files and thus your updates should never happen.

To resolve your problem: I would split your application in two. One part ensures the other part has the latest version, then executes that latest version.

For Java, something like this has been developed many years ago as WebStart technology, was marked as deprecated for Java 9 and removed thereafter. Meanwhile there is the project https://openwebstart.com/ that you might want to check out.

Queeg
  • 7,748
  • 1
  • 16
  • 42