Process automatically exiting after starting in Process builder - process

I am trying to have the multiprocessing functionality . When I try to run a browser or any exe-based command, that process automatically exits whereas my java jar is running and only exits when I close them. Below is my sample code using
process = processbuilder.start(launchCommand);
CompletableFuture<Process> onProcessExit = process.onExit();
onProcessExit.then(ph -> functiontocallAfterClose();

Related

having a problem waiting for ctest_submit

I'm having a problem when using ctest_submit() to submit my build results for the dashboard server. I'm trying to build my project using ctest_build() and then i submit the results using ctest_submit(). However, i don't want to wait for ctest_submit() to finish submitting the results before continue executing the rest of the cmake script. Instead, i want to trigger the submission and continue executing the script without waiting for the cmake_submit() to finish. Is there anyway i can do this ?

Start another program then quit

From a program A written in rust, I want to start a program B, have A end, and have B normally run just like if it was manually launched from the same shell just after termination of A.
My current program:
use std::process::Command;
pub fn execute(exe: &str, args: &[&str]) {
Command::new(exe)
.args(args)
.spawn()
.expect("failed to start external executable");
}
fn main() {
execute("/usr/bin/nvim", &["/home/dys/todo.txt"]);
}
This fails. nvim is launched as a child and is non-working as soon as the calling program stops.
How can I write execute so the caller program immediately stops and lets nvim (or another program) properly run (even without any windowing system) ?
After further discussion, we identified the actual problem: The program you are launching is supposed to stay in the foreground, so it can read from the terminal (which background processes can't do on Unix).
There are two ways to achieve this. The first, and easiest, is to wait for the child process before the parent process exits:
use std::process::{Command, ExitStatus};
use std::io::Result;
pub fn execute(exe: &str, args: &[&str]) -> Result<ExitStatus> {
Command::new(exe).args(args).spawn()?.wait()
}
This ensures the processes (parent and child) stay in the foreground, since the shell is waiting for the parent process, so the child process can read from the terminal.
If for some reason you can't afford the parent process to linger on while the child process is running, you need platform-dependent code. On Unix, you can use some syscall from the exec() familiy to replace the image of the parent process with the image of the child process:
use std::process::Command;
use std::os::unix::process::CommandExt;
use std::io::Error;
pub fn execute(exe: &str, args: &[&str]) -> Error {
Command::new(exe).args(args).exec()
}
The function only returns if there is an error. Otherwise, the process image is replaced by the new image. From the viewpoint of the shell, it's still the same process, so the shell will wait for the command you launched to finish.
The advantages of the second approach seem slim. It does not work on Windows, since Windows does not support exec() and friends. You will have one less process around while running the command, but the resource usage of that process should be small in practice – it does not use any CPU, and the memory pages can be swapped out if necessary.
Original Answer
From a program A written in rust, I want to start a program B, have A end, and have B normally run just like if it was manually launched from the same shell just after termination of A.
This is more or less what your code is already doing. There are a few differences to a process launched directly from the shell on Unix systems, though:
The new process will not be included in the shell's job list, so you can't use the shell's job control commands like bg and fg.
The new process will run in the background, and the shell will immediately show a prompt after the Rust programs exits.
This fails because nvim is launched as a child and is killed as soon as the calling program stops.
This is not true, neither for Unix nor for Windows.
How can I write execute so the caller program immediately stops and lets nvim (or another program) properly run (even without any windowing system)?
This should be exactly what your Rust code is doing (and what it does when run on my Linux machine). The code in your answer, on the other hand, does something else: It uses execv() to replace the Rust process with nvim. In effect, the process does not immediately stop, and the shell remaind blocked until nvim exits.
Here's a working solution on linux, using a wrapping ot the execv function:
use nix::unistd;
use std::ffi::CString;
pub fn executev(args: &[&str]) {
let mut args: Vec<CString> = args.iter()
.map(|t| CString::new(*t).expect("not a proper CString"))
.collect();
unistd::execv(
&args[0],
&args,
).expect("failed");
}
fn main() {
executev(&["/usr/bin/nvim", "/home/dys/todo.txt"]);
}
Note: This does start another program and quit but be wary that replacing the current process implies you properly closed open resources. If you can accept having your program kept alive, you probably want to wait as suggested by Sven Marnach.

Call an external program to run as standard user from a requiredAdministrator program

My Visual Basic program will copy files to a program files folder, so I have to use requiredAdministrator privileges since asInvoker won't allow to write in the program files folder.
After I copy the files I invoke an AutoIt script automating setup of files within the external program (for that the script calls the external program to start automation). The program that creates and copies the files to the "end" program functions fine. The script that calls the "end" program and does the automatic setup also works.
When I combine the 2 the "end" program (which I didn't write nor have the source code of) behaves erratically when run as admin (doesn't read the database or the needed files return an error and terminates itself). So run as admin is not an option. But since my program has to run as admin it looks like it passes the sames privileges to the AutoIt script which calls the "end" program as admin as well. It also happens if I call the "end" program from my app instead of the AutoIt script.
Is there any way to demote my app from admin to standard user after it copies the files, right before it calls either the AutoIt script or the "end" program so that the "end" program is not run as admin or a parameter that specifically makes the app to call the external program as standard user?
I'm using Process.start("autoitscript.exe") to call it. Or any other workaround that doesn't involve the AutoIt script calling the "end" program and my app because that works but not as I intent.
This is a tricky task to perform, but how about this:
Have your application start asInvoker, don't show any windows, and make check if it runs with elevated privileges using this code:
Public Shared Function IsAdministrator() As Boolean
Return (New WindowsPrincipal(WindowsIdentity.GetCurrent())).IsInRole(WindowsBuiltInRole.Administrator)
End Function
If it's not running with elevated privileges make it start an invisible cmd instance where you redirect the standard input.
Get the cmd process's PID and now start a new instance of your application with elevated privileges (can be done by setting StartInfo.Verb = "runas") and pass the PID as a command-line parameter.
Now your new instance of the app starts and IsAdministrator() should return True.
So now that you know that your app has administrator privileges you can check if the app has a command-line parameter that is parsable to an Integer. If so, store that Integer somewhere and then do all your admin-required work.
In the end where you want to start the autoitscript.exe application you create a process variable and assigns Process.GetProcessById(<your PID Integer here>) to it.
For example:
Dim cmdProcess As Process = Process.GetProcessById(cmdPID)
Now that you have control over the cmd instance again you just have to write to it's standard input (this article describes a little how it works).
You want to write two lines. The first is to start the other application:
autoitscript.exe
and the second is to close the cmd instance:
exit
If anything's unclear just let me know.

running code after application is closed?

i have the following problem. i am working on an auto update in my application which means i want to re-download the application. i am using DownloadFile method for this but the problem is of course i cannot download and exchange the file with my current application as long as the application is running and i can't run code after it's closed either.
this is what i am basically trying to do for ppl still didn't get my problem:
Private Sub closeApp()
Application.Exit()
' DOWNLOAD FILE AFTER PROGRAM CLOSED
End Sub
The way this is usually done is to have 2 separate programs. One is the program its self, the other is the updater. When you exit the program you spin up a copy of the updater and exit the actual program. the updater program is then free to download and overwrite the main application because the file isn't in use any more.
This can also be reversed, with the updater, sometimes called the "launcher" when used this way, acting as a stub that checks for updates to the main application when it starts. Once it sees that no update is needed, or after it updates the main program, it goes on to launch the main program and exits its self.

Is there a way to see if a selenium test is being ran via nunit or nunit-console?

So, I have a reasonable amount of Selenium Tests. I want them to run quietly in the background via a batch script, nunit-console, and RemoteWebDriver. I have this setup already. I want to also be able to run the same tests (with me watching, debugging, writing new tests, etc...) with other drivers in visual studios 2013 using nunit. I have this already setup. The problem is I want to be able to run them at the same time.
I'm thinking of putting a check in to see if the calling program is nunit vs nunit-console to determine which driver to use, but I am a little uncertain how I should set this up.
I've considered:
bool isConsole = Process.GetProcessesByName("nunit-console")
.FirstOrDefault(p => p.MainModule.FileName.StartsWith(#"C:\Program Files (x86)\NUnit 2.6.4\bin")) != default(Process);
if (isConsole)
{
// remote
}
else
{
// ff,chrome,etc...
}
This however would not allow me to run the suite quietly in the background WHILE running individual tests in visual studios.
I'm not sure if there's any difference when you're running a selenium test, but with a normal nunit test you could do:
if("nunit" == Process.GetCurrentProcess().ProcessName)) {
...
}
This gets your the name of the process that's actually executing the tests, rather than just checking if the process is currently running on the machine.
Running from within visual studio, I get a process name of "vstest.executionengine.x86", from the console, I get "nunit-console" and from the gui I get "nunit".
It's possible that depending on the process model that you're running your tests under that you might need to check the parent process, rather than the current process. With Nunit configured to run tests in a separate process the reported process name with the above code is "nunit-agent". For some reason I can't get nunit-console to run in this mode at the moment, so I don't know if it has a different process name that you can use instead.
If you do need to trace up the process call stack to see what the parent process is, there's some excellent answers on how to do it on this question.