0

I have a windows application, which is started running .bat file. This .bat file calls different things before launching the .exe. The problem is, that no matter what I do, I can get that .exe running, but as soon as the script ends, the application ends as well. I think the problem has something to do with the fact, that the .exe needs to launched via that .bat file. Here's something I have already tried with python:

subprocess.Popen(['cd','path\\to\\the\\script', '&&', 'start.bat' ], shell=True, text=True | subprocess.DETACHED_PROCESS )
time.sleep(10)

As soon as the sleep runs out, the launched .exe closes. I have also tried with different subprocess parameters, such as subprocess.CREATE_NEW_PROCESS_GROUP but no luck.

I have also tried:

os.system('cd "path\\to\\the\\script" && "start.bat"')

And the same thing. I have already tried answers found from here, but no luck.

So is there some other way to launch that .bat file and somehow leave it "truly", because I think the problem is, that when the .bat file has done it's job, it exits and this somehow messes things up.

Creating infinite loop in python after calling the .bat doesn't sound like a good solution either just to keep the calling process running.

No, I can not just call the .exe directly.

ADDITION: The .exe that I launch, must stay on basically forever.

DeadlyHigh
  • 94
  • 8
  • Doesn't DETACHED_PROCESS make this new process a completely new one and, consequently, would not be waited? – Itération 122442 Aug 11 '23 at 06:32
  • Does this answer your question? [wait process until all subprocess finish?](https://stackoverflow.com/questions/15107714/wait-process-until-all-subprocess-finish) – Itération 122442 Aug 11 '23 at 06:37
  • Thanks for the comment! I don't think the process needs to be waited, or at least I don't think so. the end goal is to launch the application, and leave it running basically forever. There is no need to communicate with that .exe after it has been launched. – DeadlyHigh Aug 11 '23 at 07:10
  • Have you tried backgrounding it with `cd path && start.bat &` – Mark Setchell Aug 11 '23 at 09:00
  • Why are you using python to run cmd.exe which launches a batch file start an executable file? – Compo Aug 11 '23 at 11:43
  • There are multiple things wrong on using the [subprocess module](https://docs.python.org/3/library/subprocess.html), most likely caused by never reading the Python documentation for this module carefully from top to bottom and additionally also the Microsoft documentation for the Windows kernel library function [CreateProcess](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw) and [STARTUPINFO](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfow) structure. – Mofi Aug 11 '23 at 16:32
  • The Python method `subprocess.Popen` is on Windows just a Python wrapper for `CreateProcess` called without or with a `STARTUPINFO` structure. There is the `CreateProcess` function parameter `lpCurrentDirectory` which points to the string defined with parameter `cwd=` in `subprocess.Popen` call making the `cd` command not necessary at all. The current working directory can be defined by the process staring an executable like `%SystemRoot%\System32\cmd.exe` for processing a batch file. `shell=True` results in starting `cmd.exe` with the option `/C` and the Python `args` appended as arguments. – Mofi Aug 11 '23 at 16:38
  • The next mistake is naming the batch file `start.bat`. __START__ is an internal command of `cmd.exe` and belongs to the list of [Windows commands](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/windows-commands). No program or script should have ever the name of a Windows command (internal command of `cmd.exe` or name of an executable in `%SystemRoot%\System32`). Batch files should have since Windows NT4.0 the file extension `.cmd` instead of `.bat` although the difference is small on processing them by `cmd.exe`, but there is one. – Mofi Aug 11 '23 at 16:41
  • The usage of `shell=True` is not good here because of the *Windows Command Processor* should __keep__ running after processing of the batch file finished. Run in a command prompt window `cmd /?` and there is output the usage help explaining the options `/C` for running a command line and __close__ and `/K` for running a command line and __keep__ running. The goal is therefore running `%SystemRoot%\System32\cmd.exe` best with first option `/D` and second option `/K` and third the batch file name with `cwd="..."` defining the full path of the directory to use as current directory for `cmd.exe`. – Mofi Aug 11 '23 at 16:46
  • There should be used [os.environ](https://docs.python.org/3/library/os.html#os.environ) and if there is returned the Windows directory path as string, concatenate that string with `"\\System32\\cmd.exe"` to have the fully qualified file name of the *Windows Command Processor*. If there is very unlikely no string returned, use just `cmd.exe` and hope that `CreateProcess` runs `%SystemRoot%\System32\cmd.exe`. `SystemRoot` is not defined if a user opens a command prompt window, runs next `set SystemRoot=` and then starts `python.exe` with the Python script file name as argument which nobody does. – Mofi Aug 11 '23 at 16:52
  • The other arguments in `args` list are `"/D"` and `"/K"` and the batch file name which should be something other than `start.bat`, a more meaningful name with file extension `.cmd`. `shell=True` must be removed from the list of parameters passed to `subprocess.Popen`. `text=True` must be also removed. It is impossible to capture the output of detached started `cmd.exe` which keeps running after batch file processing finished and makes the batch file processing independent on Python script interpretation which immediately continues. – Mofi Aug 11 '23 at 16:59

2 Answers2

0

After running the .exe you could check for whether it runs or not (see this thread)

It would be something along the lines of:

import psutil
while True:
    if "YourEXEProcess" in (p.name() for p in psutil.process_iter(attrs=['name'])):
        time.sleep(some appropriate amount of time)
    else:
        break
end script
Pharmand
  • 1
  • 2
0

First: please don't name your bat file "Start.bat" it could cause some problem because start is a command and when executing batch file, it could cause to infinite loop <3

Second: That's not seem to be a python problem, it seems batch file should handle this. So you can solve this problem in batch file by using this line:

call "cmd /c start notepad.exe"

just replace notepad.exe with your exe filename


Third: I made this python script:

import subprocess
subprocess.Popen(r"D:\draw\StartApp.bat")

and this batch:

cd /D "%~dp0"
call "cmd /c start draw.exe"

work as excepted. hope to help you too.


Finally more information about "call" and "start":

call runs the given script inside the same interpreter instance, so it can only be used for batch files, but it allows the called script to modify the caller's environment using set. In Windows NT, call also allows labels to be called as subroutines; e.g. call :foo.

On the other hand, start uses the ShellExecute() function, so it can be used to open practically everything Windows itself can open, including documents, other files, and even Internet URLs. start also has options to open a separate console window, to use different process priorities, and to run a program without waiting for it to finish. However, if you use start with a batch file, it will run in a separate interpreter, and any modifications to the environment will not be seen from the caller.