Java ProcessBuilder - run command/bat File as Administrator - java

I'm using a third-party software (MFT) in my program, which is used for updating and receiving information from Network Cards.
In order to get information, I need to use the command mst status which requires Admin privileges.
So far, I've been using ProcessBuilder to execute commands directly out of my software. However, when my programm reaches this command, I just get "Only administrators can get the devices list" as answer.
I've tried creating a .bat-File, and then creating a shortcut to it, selecting "Run as Administrator" in its properties. However, with this approach the software returns "" as result.
Through so manual testing with the files themselves, I figured out that the shortcut never returns anything, and if I start the bat File without using the shortcut, I get the old "Only administrators..." again
Is there any other way I could execute this command with Administrator Privileges?

Related

Launch program from batch file generated by Java

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?
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.

How to move Java runtime console to different terminal window?

I executed a Java program from the command line in terminal app A. I want to move the console to terminal app B without having to exit and re-execute the program.
I can think of a few potential ways to solve this, ranging from:
A) In Java implement a new InputStream and OutputStream that somehow can be wired to a new process started in terminal app B.
...to
B) Find a way to put the main Java process in terminal app A in the "background" so that original process can be reopened in a terminal app B.
Ideally, I want to be able to "log in to" and "log out of" my Java process from any terminal on my computer. Has anything like this already been accomplished, and which approach would be best to make it myself? I am open to solutions that involve Java code, shell scripts, or both.
My specs:
OSX: 10.12.4
Usually running zsh on iTerm
If I was using Linux, the perfect solution would be reptyr, a command line tool that allows you to easily switch terminal windows.
On Mac, the best solution I have found is screen. It can also be used to switch terminal windows but must be invoked before running java in order to work and seems a lot more complex.

How to launch a .jar that needs elevated privileges?

I have a little .jar that executes a simple system administration task and so it needs to be run with elevated privilege. I've been researching this for hours and now know that it can be done in three ways:
1) ran from an elevated cmd prompt
2) convert the .jar to .exe and bundle it with a manifest file
3) use another .jar to launch my .jar and ask for permission.
Option 1) won't work for me because this will need to be deployed to other users that won't know how to do this. Option 2) isn't ideal because I chose to write this app in Java for its portability. This will likely be run on different systems and Java seems the most compatible. So that leaves Option 3) and is where my question comes in. I can't seem to sift through the multitude of info out there on how to accomplish creating a wrapper for my app. With my specs in mind what do you all recommend for creating a wrapper .jar that will prompt the user to allow my .jar to run? Thanks
On Windows, it is possible to run a Java application either as a desktop application, or as a Windows Service in the background. In the case of a Service, the Wrapper needs to be able to be installed, removed, started, stopped, have its status queried, etc. Depending on whether the application has a GUI or is meant to be run in a command window also determines how it will be run.
On Windows systems, the most way of launching the Wrapper is to make use of dedicated batch files to perform each action of controlling the Wrapper. This makes it possible for the end user to double click on the batch file icons or set up links in menus, just have a look if you have the java runtime env.
Nice tutorial: http://wrapper.tanukisoftware.com/doc/english/qna-service.html
Here it has some other possibilities, using Dedicated Batch File, Command Based Batch File or Standalone Binary : http://wrapper.tanukisoftware.com/doc/english/launch-win.html#dedicated
Think you can do this with .bat file. Make sure you have java runtime env, so that you can execute jar file using java -jar command.
If your looking to force the user to use elevated permissions then pure Java isn't going to cut it. I suggest you write native code and use the Java Native Interface (JNI)

Controlling Process Name of my Jar

I wanted to know is there any way I could control the name the process my jar is starting, i.e,
I created a .jar file in java and whenever I am clicking on it, it is causing a process named javaw.exe and I want to control this name.
I want to do so because when I click on my jar file then if it already running it should stop and a new one should start, i.e., I want to run a new thread (process) everytime I click on it by stopping the previous one.
If I kill the process named javaw.exe, all processes with name javaw.exe would die (if I am running more than one program) . So, I need to change its name.
Plz help.
Thanks !
There's nothing wrong with javaw running. From the documentation:
The javaw command is identical to java, except that with javaw there is no associated console window. Use javaw when you don't want a command prompt window to appear. The javaw launcher will, however, display a dialog box with error information if a launch fails for some reason.
Ultimately, javaw runs your program without a console window. Changing that name could lead to some serious issues later, so you'd want to keep that particular program name.
Why reinvent the wheel? There are already standard ways to prevent two copies of the same program from running. Typically it involves creating a "flag" file, since filesystems guarantee that directory updates are atomic. On UNIX-like systems, the file would be /var/run/program-name.pid. If it already exists, then the second copy will exit with an error.
You could setup a controller process, that manages your instances:
First you try to connect to the controller on localhost via tcp/ip at a specific port (your programs "name" from now) and if sucessful, you send a message like 'new instance started' to that controller. If the connection was not sucessful, you start a new controller-thread in the current vm (and send the message again to this thread)
the controller loops, waiting for messages and if one matches 'new instance started', it does what you describe.
such a controller can be built easily using a simple ServerSocket, a small HTTP-server or many other messaging libs.

Windows: Running privileged command from non-privileged using CMD (or Java)

I will have a service that runs as administrator and listens on a port. My GUI program will talk to the administrator service for the items that require administrator privileges.
If the service is not yet running, I will need to start it. How can I get my GUI program to run a command as administrator? I assume the user will be asked if they want to continue.
I am hoping there is something I could type in a CMD window because that should fit very well into my Java program. I am thinking something like run-as-admin javaw my-service.jar where run-as-admin is the command that asks whether to continue or not.
Windows contains the tool "runas" which can be used to start any executable with a different user account.
On the commandline you would then use:
runas /user:Administrator "javaw -jar my-service.jar"
The only drawback is, that you need to type in the password, you cannot supply the password as an argument to the runas command
You have a problem here. Non admin processes cannot start services. The very simplest thing to do is to arrange that the service starts automatically. I'd strongly recommend you take that route.
What you are thinking of doing would involve creating a helper application that includes the UAC manifest with requestedExecutionLevel set to requireAdministrator. This helper app could then start the service. The problem with this is that it requires that the logged on user is in the administrators group which you cannot guarantee will be the case.
All in all, starting the service automatically is to be preferred.
You can't execute a batch file as administrator. You need to create a shortcut to that file and then set the flag in the Shortcut 'Execute as Administrator', if this is really what you want to do.
To do this from the desktop, select the Shortcut, right click and Properties->Shortcut tab->Advanced button. Then check Execute as Administrator checkbox.
To do this programmatically, see How to set "Run as administrator" flag on shortcut created by MSI installer
We use the Wrapper library for this:
http://sourceforge.net/projects/wrapper/
The official website seems to be suffering from dynamic dns issues at the moment, so here is the wayback archive version.
From the command line (and by extension, Java) you can install, uninstall, start, and stop your Java application as a service.

Categories