【问题标题】:How to run a batch script without the window flashing?如何在不闪烁窗口的情况下运行批处理脚本?
【发布时间】:2021-08-17 15:27:31
【问题描述】:

使用上一个问题 (Kill process after timeout when homonym processes are open - batch) 的建议,我能够在超时后杀死同音进程:

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

但是,我想在不显示(和闪烁)窗口的情况下启动该过程。 我发现了很多问题,例如:How to run a PowerShell script without displaying a window? 但我无法将它们结合到我的脚本中。我该怎么做?

感谢您的帮助

【问题讨论】:

  • 你试过隐藏“-WindowStyle”吗? Start-Process 具有相同的参数。
  • @mklement0 你如何看待像 PS2Exe 这样的“编译”脚本。我还没有尝试过,但是从我的阅读来看,它似乎利用了备用主机。它还有一个-NoConsole 参数可以满足要求。诚然,将脚本包装在 EXE 中以包装在 BAT 中似乎有点俄罗斯娃娃,但至少应该解决隐藏窗口的核心问题。另外,我知道可能存在 VS 误报问题......我几乎把它放在一个带有参考的答案中,但认为现在作为评论可能会更好。
  • @Steven,是的,PS2Exe-GUI 是一个选项,尽管 AV 软件可能(错误地)抱怨它;请看我的回答,它试图概述各种选项。

标签: powershell batch-file


【解决方案1】:

根据 Steven 的评论,我也在循环中添加了 -WindowStyle Hidden。这里的解决方案:

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

【讨论】:

    【解决方案2】:

    tl;博士

    要隐藏通过控制台应用程序使用Start-Process 产生的控制台窗口(在您的情况下为myapp.exe),请使用-WindowStyle Hidden,如in your answer 所示,但您还可以通过在单个 powershell.exe 调用中执行 all 操作来简化和缩短您的代码:

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

    用例:

    • 您想要的是隐藏默认情况下由 PowerShell 的 Start-Process 启动 控制台应用程序 产生的控制台窗口(通常不会这样做,因为 直接同步执行是迄今为止最常见的用例 - 请参阅this answer):

      • -WindowStyle Hidden 隐藏这个新窗口;请注意,除非您通过
        -RedirectStandardOutput-RedirectStandardError 参数请求重定向到文件,否则您将无法查看或捕获任何输出;另外,为了检查退出代码,您需要使用-PassThru 来获取代表新启动进程的对象。

      • 如果您想在 当前 控制台窗口中查看程序的输出 - 尽管无法捕获它 - 请使用 -NoNewWindow ,但是,只有在您还使用 -Wait 时才有意义,否则异步运行的程序的输出会干扰您的显示(如果您仍然在等待,直接同步调用是更好的选择)。

      • 顺便说一句:在类 Unix 平台上,-WindowStyle 不受支持,-NoNewWindow隐含的,这使得Start-Process 仅对启动 GUI Unix 上的程序(包括启动 URL 以便在默认 Web 浏览器中打开它们;例如 Start-Process http://example.org

    • 但是,您的问题标题可能会让人们认为您的意图是运行批处理文件本身 - 或任何控制台应用程序 - 不可见

      • Windows 没有为此提供直接机制;启动控制台应用程序总是会为其创建一个可见控制台。因此,一个解决方案需要一个 GUI-subsystem 帮助文件或机制,它 (a) 本身不创建控制台窗口,并且 (b) 允许在启动时隐藏自动控制台窗口目标控制台应用程序。

      • 有几个解决方案

        • 拨打mshta.exe:;一个简单的例子,运行powershell.exe 本身不可见并最终打开记事本;您可以从 Windows Run 对话框 (Win-R) 运行它,以验证没有为 PowerShell 创建控制台窗口:

           mshta.exe vbscript:(CreateObject("WScript.Shell").Run("powershell -c notepad.exe",0))(Window.Close)
          
          • 警告:反病毒软件可能会阻止这种调用机制。
        • 使用通过 GUI 子系统 wscript.exe 主机启动的辅助 WSH 脚本*.vbs*.js) - 请参阅 this answer

        • 使用第三方RunHiddenConsole 项目,该项目提供您为目标可执行文件命名的通用 GUI 子系统helper 可执行文件附加w

        • PowerShell 的上下文中,具体来说:

          • 为第三方 PS2EXE-GUI 脚​​本 可以为您创建的 PowerShell 脚本使用 GUI 子系统 wrapper executable;示例见this answer

            • 注意:生成包装器的脚本必须在 Windows PowerShell 中运行,并且生成的 *.exe 也可以通过 Windows PowerShell SDK 执行。
          • PowerShell (Core) CLIpwsh.exe 本身可能在未来提供解决方案,正如GitHub issue #3028 中所讨论的那样(未来对条件控制台分配的增强PowerShell 可以利用的控制台子系统)。

    【讨论】:

      猜你喜欢
      • 2021-12-21
      • 1970-01-01
      • 2010-09-25
      • 2010-12-20
      • 2022-06-13
      • 2012-02-07
      • 2012-10-30
      相关资源
      最近更新 更多