I am trying to detect if a subprocess in currently running via CMD, But I have no idea how to do that, I know how to detect a normal process, but not a subprocess
any ideas?
EDIT: I am running a program, if the program finishes it opens a new window, i want to detect when that window opens
If the window only shows up when the program closes, then you could check if the program is still running, and if not running, then the window will be shown.
To check if program is running, use one of these solutions:
How to check if a process is running via a batch script
Related
When I open a program in C from the VS editor (I mean pressing the green button "Local windows debugger") the console opens, stays open and the program finishes noramlly.
However, when I try to run the program manually from the .ext file created, the program runs but the console opens for a brief time and closes immediately. How can I fix it?
I have a application written in C and i want to control writing of syslogs in txt file from application. On application there is option for START/STOP running, so basically when i press START i want to start writing syslog(journalctl) to /some_folder/debug.txt, and when i press STOP i want to close the file.
This can be done by linux command "journalctl [parameter] > /some_folder/debug.txt", but that is not enough, this must be controlled from application.
Does anyone have idea how this can be done properly, is there some API to control syslogs or i have to do it via system()?
If there is no way, if i have to use system() and journalctl commands are there some suggestion which commands to use?
I'm sure my question has probably been answered previously but I didn't find anything specific to my situation after searching for a while.
Background:
I have written a suite of data acquisition tools in C that run on an embedded system running Debian Wheezy. There is a main module, called Dispatch, whose job is to launch the rest of the modules and pass messages between them. I put a trivial bash script in /etc/init.d that executes Dispatch when the system boots since this system runs unattended. This system runs without any local user interaction so Dispatch should really be written to function as a daemon but it is not. The startup script simply executes /opt/bcdispatch &.
There's a bug in one of the other modules that causes it to crash every few days. I'm trying to hunt down that bug but in the meantime I am trying to write a watchdog program that will detect the crash, kill off all of my processes, then relaunch Dispatch. For reasons I won't go into it is not sufficient to just relaunch the crashed process, the whole suite of tools needs to be restarted.
What I'm trying to do:
I wrote a simple watchdog program that periodically executes popen("ps aux | grep bc") (all of my process names start with "bc" which makes it easy to find them with grep), finds that one of the modules has crashed by looking for anything with a "zombie" status in any of the lines read from popen(), kills all of my processes by calling system("kill <PID>"), then executes the startup script in /etc/init.d and exits. I modified the startup script so that it launches the watchdog after launching Dispatch. The startup script now looks like:
/opt/bcdispatch &
/opt/mywatchdog &
Everything is being run as root. There are no other user accounts on the system.
Problem
The watchdog process works fine if I run it from the command line. It kills off all of the processes it's supposed to, launches the startup script, then exits. However, when the watchdog is launched by the startup script at boot time it doesn't do its thing. It's running, one of the processes it's monitoring has crashed, but it doesn't kill the rest of them off. It just sits there like a giant turd. I can start another instance of it from the command line and that one works just fine.
Question
So my question (finally!) is: why can't my program kill other processes when launched via a startup script? I suspect it has something to do with the fact that the watchdog process no longer has a terminal associated with it? I tried substituting the call to system("kill <PID>") with kill(PID) but that didn't change anything.
EDIT
It just occurred to me that it's not the kill()ing part that doesn't work (well, that might be broken as well), the call to popen("ps aux | grep bc") must not be working since the watchdog should exit after it finds the zombie process but it isn't. Its PID is still the same as it was when the system booted. I guess this means the title of this question isn't very good.
Found the problem. The output of my watchdog's call to popen("ps aux | grep bc") was being truncated to 80 columns, presumably because it was no longer attached to a terminal and that's the default terminal width. That truncation was causing problems for the way the program was parsing the results of the ps command so it never found the crashed process. Changing the command to popen("ps -w aux | grep bc") was all that was needed to fix it.
There are many references on Internet claiming that one of differences between a GUI and a console application is that running the GUI application from a batch file does not block its execution, while running the console application does block it.
Few of many references, these are particularly from SO/SE:
How can I get an MFC application to block from the command line?
How to wait for a process to terminate to execute another process in batch file
How do you wait for an exe to complete in batch file?
Run a program in a batch script and wait for it to finish before continuing
Moreover, I myself remember this is/was true.
Yet it does not seem to work this way.
I've tested this on a simple batch file like:
echo Pre
notepad
echo Post
The Post is not printed until I close notepad. Why, when a notepad is clearly a GUI application?
I've tested this on Windows 8, 7, and XP just to rule out a possibility that the behavior has changed in recent versions of Windows. I've tried to disable command extensions as one of possible culprits too.
It has to do with how the application that you launch runs and terminates. Some programs launch another process and then terminate, others continue to run. Calc.exe and Notepad.exe simply run until you close them. Write.exe and any program that launches as a result of a file association (e.g., bitmap, wave file, control panel applet, etc.), actually launch another program and then the process that launched them terminates returning control back to the batch file so it can execute the next line.
Here are some examples:
#echo off
echo Starting Calc.exe
calc.exe
echo Calc was closed by the user
echo Starting Notepad.exe
Notepad.exe
echo Notepad was closed by the user
echo Starting WordPad.exe
write.exe
echo Write launched WordPad and then terminated allowing the batchfile to continue
echo Starting Services.msc
services.msc
echo Windows launched MMC, opened services.msc, then returned control to the batchfile
echo Launching WMP via Chord.wav
c:\windows\media\chord.wav
echo Windows launched WMP, opened Chord.wav, then returned control to the batchfile
The CMD process knows Calc and Notepad are still running because it spawned them itself. The CMD process does not know that the others are still running because the intermediate process terminated.
To observe this, open Process Explorer and view the processes displayed in the hierarchical tree. Calc.exe and Notepad.exe both remain as child processes of the CMD process that ran the batchfile. Write.exe and MMC.exe (services.msc) both become top-level processes, no longer children to the CMD process. WMPlayer.exe remains a child process to svchost.exe, which is how Windows launched it. The CMD process doesn't know they are still running because it didn't launch them, some other Windows process did. So execution continues...
One more example of this is how MSPaint.exe functions. If you run it by using the Windows built-in file association for BMPs, then Windows launches MSPaint.exe and control is immediately returned to the batchfile. However, if you pass the BMP to MSPaint.exe, then the batchfile waits for you to close MSPaint before continuing. (I'm on a dev machine with no BMPs, so create a simple one called C:\MyBitmap.bmp.)
#echo off
C:\MyBitmap.bmp
calc.exe
mspaint.exe C:\MyBitmap.bmp
notepad.exe
Calc.exe will open immediately, Notepad.exe will not open until you close the second instance of MSPaint.exe.
I know you didn't ask about launching Windows processes via their file association, but it just demonstrates how the owning process can change. If the CMD process owns the launched process, it should wait until it terminates to continue execution. If the spawned process hands control off to another process, then the CMD process doesn't know about the grandchild process and it continues on with its execution.
Because it waits for return code.You can use start command to create a separate subprocess:
#echo pre
#start "notepad" notepad
#echo post
I've used Windows since NT 3.1, and I too would have said "cmd.exe does not wait for GUI programs to terminate" when you simply type the name of the program (as opposed to using the START command). Though memory grows dim, I believe it originally worked this way. But today, my statement is true interactively, false for "batch" files. Having been thus reminded, I vaguely think it was intentionally changed as some point, since the naïve batch-writer expects sequential execution, but I can't be sure and I don't know when.
I think the answer lies in this question Difference between Windows and Console application.
I quote from two answers.
Konrad Rudolph answered:
The sole difference is that a console application always spawns a console if it isn't started from one (or the console is actively suppressed on startup). A windows application, on the other hand, does not spawn a console. It can still attach to an existant console or create a new one using AllocConsole.
This makes Windows applications better suited for GUI applications or background applications because you usually don't want to have a terminal window created for those.
oefe answered:
Console and Windows applications behave differently when called interactively from the command prompt:
When you start a console application, the command prompt doesn't return until the console application exits. When you start a windows application, the command returns immediately.
This is not true for batch files; they will always wait until the application exits.
The difference in this bahviour between cmd and batch made you think that it worked before.
I've coded a program in c for an embedded system (Devkit8000, which is a clone of the well known BeagleBoard) running Angstrom Linux.
The program creates a couple of threads, on of them is responsible of taking pictures with a camera connected to the board, and right now the second thread only moves that images to another path. The program should be running during the whole day, and the only way to stop it is sending a signal.
I edited the crontab to launch the program in a specific hour and to send a signal when it has to stop, the issue is that launching the program in this way cause the process to be killed after some time running, but, if i launch the program manually (through the command line), it works perfectly and dont get stopped.
I have no idea about the reason of this different behaviour between crontab and command line. I've checked the system logs but didnt find anything useful. I've also been reading a little and find that the OS can kill a process if it is using so much resources, but doesnt make sense that this happens in only 1 scenario (crontab vs manually)...
Any clue about what is happening?
Thank you in advance!
The main difference is that running a job through cron invokes a non-interactive non-login shell. The effect of that depends on the default shell for your user. For example, if you are using Korn shell or Bash then your .profile will not be executed, as it would on an interactive login shell. Korn shell 88 will execute .kshrc (the $ENV file) but ksh93 will not.
So, a good start might be to call your program from a script, after first "sourcing" your .profile file:
. $HOME/.profile
Failing that... When you say that the process is "killed", do you get such a message? If so, then that sounds like someone sending SIGKILL, i.e. kill -9. If not, then maybe you could run strace or ltrace to find out at what point it dies.