From within a Java application on macOS, I use Runtime.getRuntime().exec("open -Wn filename") to launch a file with its Default application, lets call it the Viewing application (for example AdobeReader for pdf). That works fine.
My issue arises, when I want to close the viewing application (for example AdobeReader).
The problem is, that the open command itself is launched as a child process of the java application, but the open command launches the viewing application not as a child process, but as child of launchd(1). As a result, when I destroy the process from the Java application, only the open process is killed, but not the viewing application.
So far I could not manage to get a PID of the viewing application process to be able to kill it. With a ps I can only find it, when I have the application name, but that is exactly what I do not have, since I want to let the os decide about the viewing application.
Does anybody have an idea how I could
get the pid of the application that is launched from the open command, without knowing the applications Name or UTI(remember, open is not the parent process of the viewing application)?
or
make the launched application a child of the open process, so I can kill it by killing the open process?
or
any other possible solution?
Your ideas are very much appreciated.
I found a solution by getting the pid from the lsof command, since I know the filename:
lsof -t filename
Having the pid, I can kill the process, means the Viewing Application:
kill $(lsof -t filename)
The full solution looks like this:
String killCommand = "kill $(lsof -t " + filename+ ")";
ProcessBuilder builder = new ProcessBuilder("bash", "-c", killCommand);
builder.start();
Not very pretty, but it does the job.
Related
I am launching a new Chrome/Chromium window from the terminal with the --app parameter, trying to get the PID in the process, like so: chrome --app="data:whatever" & PID=$!
This returns a valid PID as long as the browser is not launched. However if the browser already had a window open, I get a message "Opening in existing browser session". There is still a number in the PID, but it has nothing to do with the process/window I just opened. When I run kill -0 $PID, the process is no longer there (but the app window still is of course).
Goal: I just want to know when someone closes the app that was launched form the script, and then execute some cleanup code.
I've turned a program I wrote into a service, and I have a bash script that runs to start up the actual program, since there are things that have to be started in a particular order. The contents of the startup script (called with start-stop-daemon from the init.d script look like :
./rfid_reader &
sleep 2
java ReaderClass &
This works fine, but how do I go about killing them when it comes time to stop the process?
I've seen pidfiles used, do I just get the PIDs of the two programs, write them to a file, and then kill them when it comes time to shut them down, or do I have to ps -ef | grep program to get their PIDs?
I don't think killall is a good idea to do this. You'd better to record the PID of the program started in background in some file(e.g. PID_FILE) and then kill $(<$PID_FILE) to stop it.
Please refer to this thread for how to get the PID the previous started background program.
Assuming you know the name of your program, you can kill them as below :
killall -KILL program_name
I'm doing my project and I need to log keystrokes system wide in macOS. So, I turned over to GitHub and found Swift-Keylogger. The only problem is I can't quit the Terminal while the program is still running.
Is there any way to not to run this in terminal or closing the terminal window instead of creating a mac app like here.
Note: There are some mac app style executables in github but they are not providing the output I want and some need additional permissions.
Instead of running the executable like ./Keylogger use nohup ./Keylogger &.
You can quit the Terminal after executing the command.
To kill the Keylogger, run ps -e | grep "Keylogger" to get pid and kill -9 pid.
P.S. I thought of adding it as well as running at startup but I'm too lazy to update the repository.
All,
I've got a problem which I need your help.
Using Ruby 1.9.3 in Windows, I'm starting a browser with the following command:
system('start http://www.stackoverflow.com')
I've tried getting the pid of the above system cmd in various ways like exec, Thread and IO.popen. But everytime I get the different PID which I assume the PID of the ruby process.
But I need the PID of the started browser, so that I can kill the browser once I finish my task at the end.
Note that I don't want to use Watir / Selenium or any automation tool.
Kindly help me on this.
Don't use start, it will spawn new window, open browser and then detach the window. Specify the browser path explicitly to solve the problem:
browser = %q{"C:\Program Files\Internet Explorer\iexplore.exe"}
pipe = IO.popen("#{browser} http://www.stackoverflow.com")
puts pipe.pid
Process.kill(9, pipe.pid)
Run start /? for help message of start command.
I searched the web for that question and landed on Server Fault:
Can I send some text to the STDIN of an active process running in a screen session?
Seems like it is ridiculously easy to achieve this under Linux. But I need it for a Win32 Command Prompt.
Background: I have an application that polls STDIN and if I press the x key, the application terminates. Now, I want to do some automated testing, test the application and then shut it down.
Note: Just killing the process is not an option since I'm currently investigating problems that arise during the shutdown of my application.
.NET framework's Process and ProcessStartInfo classes can be used to create and control a process. Since Windows PowerShell can be used to instantiate .NET objects, the ability to control almost every aspect of a process is available from within PowerShell.
Here's how you can send the dir command to a cmd.exe process (make sure to wrap this in a .ps1 file and then execute the script):
$psi = New-Object System.Diagnostics.ProcessStartInfo;
$psi.FileName = "cmd.exe"; #process file
$psi.UseShellExecute = $false; #start the process from it's own executable file
$psi.RedirectStandardInput = $true; #enable the process to read from standard input
$p = [System.Diagnostics.Process]::Start($psi);
Start-Sleep -s 2 #wait 2 seconds so that the process can be up and running
$p.StandardInput.WriteLine("dir"); #StandardInput property of the Process is a .NET StreamWriter object