1

using suggestions from a previous a question (Kill process after timeout when homonym processes are open - batch) I was able to kill homonym processes after a timeout:

popd
pushd mypath
for /f %%i in ('powershell "(Start-Process myapp.exe -passthru).ID"') do (
timeout /t 180
taskkill /PID %%i
)

However, I would like to start the process without a window displaying (and flashing). I found many questions, such as: How to run a PowerShell script without displaying a window? but I was not able to combine them to my script. How can I do that?

Thank you for your help

Matt_4
  • 147
  • 1
  • 12
  • 2
    Did you try ‘-WindowStyle’ hidden? Start-Process has the same same parameter. – Steven May 29 '21 at 19:46
  • @mklement0 what do you think about something like PS2Exe to "compile" the script. I haven't tried this but, from my reading it seems like it leverages an alternate host. It also has a `-NoConsole` parameter that may satisfy the requirement. Admittedly, wrapping a script in an EXE to wrap in a BAT seems a little Russian doll, but should at least address the core question of hiding the window. Also, I know there may be VS false positive issues... I almost put this in an answer with references, but thought it might be better as a comment for now. – Steven May 30 '21 at 02:28
  • @Steven, yes, PS2Exe-GUI is an option, though AV software may (mistakenly) complain about it; please see my answer, which tries to give an overview of the various options. – mklement0 May 30 '21 at 13:37

2 Answers2

2

Following Steven's comment I added -WindowStyle Hidden also inside the loop. Here the solution:

pushd mypath
for /f %%i in ('powershell -WindowStyle Hidden -"(Start-Process myapp.exe -passthru -WindowStyle Hidden).ID"') do (
timeout /t 180
taskkill /PID %%i
)
Matt_4
  • 147
  • 1
  • 12
2

tl; dr

To hide only the console window that results from use of Start-Process with a console application (myapp.exe in your case), use -WindowStyle Hidden, as shown in your answer, but you can also streamline and shorten your code by performing all operations in a single powershell.exe call:

@echo off

powershell.exe -c "if (-not ($ps = Start-Process -WindowStyle Hidden myapp.exe -PassThru).WaitForExit(60000)) { Stop-Process $ps }"

Use cases:

  • What you wanted is to hide the console window that by default results from PowerShell's Start-Process launching a console application (which isn't normally done, because direct, synchronous execution is by far the most common use case - see this answer):

    • -WindowStyle Hidden hides this new window; note that you won't be able to see or capture any output, unless you request redirection to files via the
      -RedirectStandardOutput and -RedirectStandardError parameters; also, in order to check the exit code you need to use -PassThru so as to obtain an object that represents the newly launched process.

    • If you want to see the program's output in the current console window - albeit without being able to capture it - use -NoNewWindow, which, however, only makes sense if you also use -Wait, otherwise the asynchronously running program's output will interfere with your display (and if you're waiting anyway, direct, synchronous invocation is the better option).

    • As an aside: on Unix-like platforms, -WindowStyle isn't supported, and -NoNewWindow is implied, which mostly makes Start-Process only useful for launching GUI programs on Unix (including launching URLs in order to open them in the default web browser; e.g. Start-Process http://example.org)

  • However, your question's title might lead people to think your intent is to run the batch file itself - or any console application - invisibly:

    • Windows currently offers no direct mechanism for that; launching a console application invariably creates a visible console for it. A solution therefore requires a GUI-subsystem helper file or mechanism that (a) itself doesn't create a console window and (b) allows hiding the automatically console window when launching the target console application (however, a potential future enhancement is being discussed, conditional allocation of a console, which would allow applications to decide whether or not to allocate a console based on runtime conditions, but note that only applications designed to use this feature would then offer situational no-console launching).

    • For now, there are several solutions:

      • Call via mshta.exe:; a simple example that runs powershell.exe itself invisibly and ultimately opens Notepad; you can run it from the Windows Run dialog (Win-R) to verify that no console window is created for PowerShell:

         mshta.exe vbscript:(CreateObject("WScript.Shell").Run("powershell -c notepad.exe",0))(Window.Close)
        
        • Caveat: AV software may prevent this invocation mechanism.
      • Use an auxiliary WSH script (*.vbs or *.js) launched via the GUI-subsystem wscript.exe host - see this answer.

      • Use the third-party RunHiddenConsole project, which offers a generic GUI-subsystem helper executable that you name for your target executable with w appended.

      • Use Python:

      • In the context of PowerShell, specifically:

        • Use a GUI-subsystem wrapper executable for PowerShell scripts that the third-party PS2EXE-GUI script can create for you; see this answer for an example.

          • Note: The wrapper-generating script must be run in Windows PowerShell and the resulting *.exe too executes via the Windows PowerShell SDK.
        • The PowerShell (Core) CLI, pwsh.exe, may itself offer a solution in the future, as discussed in GitHub issue #3028, based on the previously linked planned system-level enhancement, conditional console allocation).

mklement0
  • 382,024
  • 64
  • 607
  • 775