I open up an external application from my java application. How can I close this application from the same Java application?
thanks
The best you can do (without venturing into messy/complicated/platform specific stuff) is to call Process.kill() on the Process object you got when you started the external application.
I don't think this is guaranteed to close the application*, and there is a chance that it may cause it to close uncleanly; i.e. without giving the application a chance to save open files, etc.
* Indeed, on *NIX if you started a "setuid root" process from a non-root Java application, and the OS won't let it send any signals to to.
Why don't you have a batch (Windows) or script (*nix) file that start and stops that application, and then run your runtime.exec with the parameter start/stop?
UPDATE:
This may help: http://it.toolbox.com/blogs/database-solutions/kill-a-process-in-windows-bat-19875
Second Update
You can also search by exe name using: 'tasklist ^| findstr /i excel.exe'
On Windows this will fail. It's a top 25 bug (or maybe top 25 rfe), though it really isn't so much Java's fault ... On Windows any children of the parent process will not be killed when parent is killed..... and there are many ways to run afoul of this (cmd /c anything and you will be in game-over-land)
Related
I can't execute VBScript using WIX installer. Currently I have this part of WiX config:
<Binary Id='KillThatProcessBinary' SourceFile='KillThatProcess.vbs' />
<CustomAction Id="KillThatProcessAction"
Execute="immediate"
BinaryKey='KillThatProcessBinary'
VBScriptCall='KillThatProcessFunction'
Return="check"/>
<InstallExecuteSequence>
<Custom Action='KillThatProcessAction' Before='InstallValidate'/>
<ScheduleReboot After="InstallFinalize"/>
</InstallExecuteSequence>
And this VBS script (KillThatProcess.vbs):
Public Function KillThatProcessFunction()
Set oShell = WScript.CreateObject("WSCript.shell")
oShell.run "cmd /C wmic process where ""name like '%java%'"" delete"
Return 0
End Function
I already try to insert this script into CustomAction (as innerText), and add attribute: Script="vbscript". But nothing works, every time I got the error message - "There is a problem with this Windows Installer package. A script reqired for this install to complete could not be run. Contact your support personnel or package vendor."
And errors in log file:
Error 0x80070643: Failed to install MSI package.
[1A88:2FA4][2018-08-21T14:11:17]e000: Error 0x80070643: Failed to configure per-user MSI package.
[1A88:2FA4][2018-08-21T14:11:17]i319: Applied execute package: LPGateway, result: 0x80070643, restart: None
[1A88:2FA4][2018-08-21T14:11:17]e000: Error 0x80070643: Failed to execute MSI package.
I already execute this vbs script (not from installer) and it works. Anybody know what I do wrong?
There are a few issues I want to summarize:
VBA & VBScript Functions: That VBScript looks like it is actually VBA and calling VBScript in an MSI requires a bit of tweaking
to call VBScript functions properly.
Reboot: The reboot you schedule must get a better condition to avoid unexpected reboots.
Process Kill: What process are you trying to kill?
Elevation: If it is elevated you need to run the kill elevated for it to succeed. Your per-user setup is likely not set to
elevate at all (so you can generally only end processes running as yourself).
Restart Manager: Very often you do not need to kill processes, due to the Restart Manager feature of Windows that Windows
Installer tries to use. Attempt to explain this feature (look for
yellow sections).
Issue 1: That must be a VBA script and not a VBScript? For the record: I haven't seen return in VBScript? In VBScript you return from a function by setting the function name equal to whatever you want to return, quick sample:
result = IsEmptyString("")
MsgBox CStr(result)
Function IsEmptyString(str)
If str = "" Then
IsEmptyString = True
Else
IsEmptyString = False
End If
End Function
Note: The above is just a silly, rather meaningless example. For more elaborate checking try
IsBlank from ss64.com. VBScript comes with the functions IsEmpty and IsNull and IsObject.
When used in MSI files, I normally don't add a function in the VBScript, but just run the script directly, so running this VBScript should work:
MsgBox(Session.Property("ProductName"))
Inserting it into the WiX source (notice no function call specified):
<Binary Id='Sample.vbs' SourceFile='Sample.vbs' />
<CustomAction Id='Sample.vbs' VBScriptCall='' BinaryKey='Sample.vbs' Execute='immediate' Return='ignore'/>
Crucially your VBScript can still call other functions available in the same VBScript file. So in the above sample "IsEmptyString" can be called from the main "nameless" function at the top of the file.
Check Exit Code: And finally, any custom action set to check exit code can throw your setup into abort (immediate mode) or rollback (deferred mode). I would only check the exit code if you have to end the setup if the custom action can not run.
Issue 2: Reboots. This is a very serious issue in my opinion. I have seen people sent out the door for causing unexpected reboots during large scale deployments. Rebooting a knowledge worker's PC (and their managers) with a dozen Visual Studio windows open, dozens of browser windows and Word and Excel and you name it. It can cause a great deal of problems. And they may know where you live! :-)
Please read the following answer (at least its 3 bullet points at the beginning): Reboot on install, Don't reboot on uninstall
Issue 3: Process Kill. As indicated above the killing of processes is related to the reboot issues. It is not always necessary to kill processes if they are compliant with Windows Restart Manager as explained in the link above. Let me repeat it here (yellow sections should give you the gist of it - especially the second one I think).
There are a few different ways to kill processes. Note that the most common problem might be that you don't have the access rights and / or privileges to kill the process - no matter what tool or approach you use to do so.
Perhaps you can try the CloseApplication feature from the Util schema: http://wixtoolset.org/documentation/manual/v3/xsd/util/closeapplication.html
In Wix MSI: Killing a process upon uninstallation
Kill windows service forcefully in WIX (towards bottom)
Kill process using WMI / VBScript
Some people combine taskill.exe and WiX by means of the Quiet Execution Custom Action (CAQuietExec: hide command line windows). FireGiant documentation.
I am not sure which of these options to recommend. I don't like the concept of killing processes altogether, but sometimes there is no other option I guess.
I am running a java app that manages other java apps through starting them in different screen sessions. My problem is if one of these managed apps is not responding i'd like to kill its java process through my managing app.
The managing app starts other apps using screen -dmS appname java -jar path
The first thing i tried was to make my managing app run screen -S name -X quit but most of the time this only eliminates the screen session and i get stuck with a running java app that i have no access to.
The second thing i tried to research is to kill the java process itself which will in return terminate the screen but my problem is how can i get the PID of the java application?
ps -A is not helpful because it does not give any clue of the specific java application i want to kill among all others.
I need the PID to be available to my managing application or any other way that gives me the ability to terminate the java process running inside a screen.
However the best thing to solve my problem would be to be able to name the java app process.
I appreciate any help.
I solved the problem by passing an argument when i start any managed app like so:
screen -dmS helperApp java -jar path helperApp
This allowed me to identify the PID of the process among all others by doing
jps -m | grep helperApp
And since i now have the PID identified and acquired i was able to kill the process.
Thanks to everyone who helped.
I have a java application running on Windows (javaw.exe) and I would like to close the child windows through a C# application. I can see the child windows through task manager under the Applications tab but when I right-click on the child windows and click Go To Process, it takes me to the javaw.exe process running under the Processes tab.
I have tried iterating through active processes to close each window however, I am unable to find the child java windows and only can see the javaw process.
Process[] childProcesses = Process.GetProcessesByName("javaw");
I have searched the internet forums and have not been able to find a proper solution that deals with a java application running on windows to be be dealt with using C#. I'm sure there is an obvious solution so any help is much appreciated. Thanks.
If I understand correctly your problem, you want to close one or more window among many of a java application ?
You won't have child processes on javaw, you only have threads running inside the JVM. Maybe using the Threads property of the process object could help.
But even doing that, all graphic objects in a java application are rules by the AWT Thread. Killing it will mean closing all the windows.
So i don't think it's possible to do what you want to do :/
Could you try to get handle of the child window and send message to it using P\Invoke methods and calling win32 api?
Maybe this answer can cover this idea:Cannot use pinvoke to send WM_CLOSE to a Windows Explorer window
I have a .jar runnable running on my server. When I run the file locally I am able to see its output via my IDE. Similarly I can connect via SSH and run the file and see the output, but when I close the session the JAR exits.
Is there any way to have my application continuously running and then tapping into the java applications output using a terminal service like SSH without having to stop/start the application.
Any help would be appreciated.
You can use either screen or nohup
What is happening is that when you close your SSH session, there is a hangup call made to the program.
You could use nohup. Nohup stands for "no hangup"
nohup java -jar myJar.jar > outputFile.txt
That would run the program in the backround and send all output to outputFile.txt. When you end your session it will continue running. You must use a kill command to kill it.
The second option is you could use screen which essentually creates a detachable "ghost session". When you run screen it looks like you are in a different ssh session. Then when you detach from screen, the processes continues in the backround. When you exit your ssh session, screen continues to run.
You simply ssh back into the server, and re-attach to your screen session, and like magic, your program is still running with all relevent output. A simple read on the man page should catch you up on how to do this.
man screen
Lastly, I decided to add this third option, not because its viable, but simply so you can understand that it is an option. (Some people would claim this is the only REAL option as it is what your SUPPOSED to do. Frankly I couldn't care less and think you should do whatever is the easiest to get to your goal.)
You can also edit your program to swallow the hangup signal. The program would then always run in the backround. You can then use
java -jar myJar.jar & > outputFile.com
The & tells the command to start a new process (aka run in the backround) and the > sends the output to a file. This is how normal server applications like tomcat or spring boot work. They simply swallow the hangup call.
I want to install a monitoring system on a computer (the program is a jar file) and run it on start up every time any user logs on. However, I don't want the user to be able to terminate it since then it won't be able to be monitored any longer.
We have tried several ways:
Installing it as a service - the problem here is that our program doesn't work any longer; it can't connect to the computer that's monitoring it. We used "Yet Another Java Service Wrapper" for this, and looked into some other wrappers as well that could help us install it as a service.
Running the program on start up (using the folder startup), but not giving the basic user the privileges to edit/delete/mess around with the files. However, this seems to slow the whole computer down? This doesn't happen when we run the bat file executing the jar directly. Another issue with this is that the user can just go to the task manager and kill the java process.
We tried a variation of the previous one to solve the issue of the process being killed, by having another process. One will spawn the other and these 2 processes will keep tabs on each other. If one terminates, the other detects it and runs it to start it up again. Although it can have issues if the user is fast enough in killing both processes before either is respawned again, the bigger issue is that it sometimes has problems with connecting to other computers. We didn't have this problem when it was just 1 jar.
Does anyone have any idea on how these problems can be solved?
The context here is windows, but if you have suggestions for linux and mac that would be nice too!
Way to go is to run the program as a service. You should investigate any trouble between your application and your system's firewall. If you have windows firewall activated, you should add an exception for java.exe or javaw.exe.
In order to give elevated privileges to your program, you can set the service to run as another user. You can do this from the "Log on" tab in the service properties.
You'll want to have the program started under a user with elevated permissions. On WIndows this would the the Administrator, linux would use root. On Windows, its likely that you will need to start it as a service. But I really don't know why that would hinder the network communications.