【问题标题】:Is there a better way to shell out a command in C++ than system()?有没有比 system() 更好的方法在 C++ 中输出命令?
【发布时间】:2011-05-02 21:59:55
【问题描述】:

我有一个 C++ Windows 服务,当我调用 system() 函数来执行命令时,该服务有时会崩溃。我已经在 windows 命令行中运行了该命令的确切文本,它运行得很好,但是由于某种原因,它在 system() 运行时失败了。

更糟糕的是,我似乎无法获得有关 system() 失败原因的任何信息。似乎没有引发异常,因为我正在执行 catch(...) 并且没有任何内容被捕获。我的服务刚刚停止运行。我知道是对 system() 的调用失败了,因为我在调用之前和之后放置了日志信息,之后的任何内容都没有记录任何内容。

那么,有什么不同的方式可以让我执行命令吗?至少,如果出现问题,可以给我一些信息,或者至少让我处理异常或其他事情。

【问题讨论】:

    标签: c++ windows shell system


    【解决方案1】:

    您可以使用 fork/exec,但我认为这就是系统正在做的事情。

    【讨论】:

    • exec 肯定会让您更好地控制流程。许多系统还具有spawn 功能。
    • 不太可能,因为它是 Windows。更有可能是 CreateProcess 或类似的。
    • Windows API 中不存在 Fork。
    • 编辑前的问题不是特定于窗口的,因此是答案。
    【解决方案2】:

    我相信system() 在技术上是 C 标准库的一部分,因此不会抛出异常。您应该能够检查返回码或 ERRNO 变量以获取有关所发生情况的一些信息。此MSDN 链接包含有关 Windows 上可能的返回码的一些信息。

    我还看到system() 因其他外部原因(例如病毒扫描程序)而失败,因此您也可以对此进行调查。

    我不知道运行 shell 命令的更好方法,但我可能是错的。

    编辑:如果它似乎仍然无缘无故崩溃,您可以尝试使用process monitor 来查看较低级别的情况。由于进程监视器的输出可能有点压倒性,我喜欢使用的一个技巧是在调用 system() 之前向您的程序添加一条语句,以打开一个不存在的文件,如“C:\MARKER.TXT”或其他东西,然后您可以在进程监视器输出中搜索文件名,然后查看可能与问题有关的条目。

    【讨论】:

    • 问题是,当系统被调用时,我的应用程序似乎就死了。我尝试在调用系统后立即记录一些内容,但我什么也没得到。
    • 您确定传递给system() 的字符串实际上包含您想要的内容吗?作为测试,您可以尝试使用不同的命令运行 system(),例如 sleep 或其他命令,看看是否有效。
    • 运行 system("dir") 看看你有没有得到什么
    • 是的,我确定。只有一些命令会导致系统失败,我已将它们打印到我的日志文件中。我知道哪些命令失败了,正如我所说,我已经在命令行中运行同样的命令,它工作得很好。
    • 在这种情况下,我建议使用进程监视器来尝试获取更多线索。我编辑了我的答案以包含一个链接。
    【解决方案3】:

    普通的 catch() 不会捕获致命异常(例如分段错误)。您必须使用结构化异常处理。更好的是,启用事后调试; this article 解释了如何启用服务的事后调试。

    【讨论】:

      【解决方案4】:

      我认为您的问题可能是与您的服务关联的用户帐户。

      要么是环境问题(路径中缺少条目),要么是服务用于运行的帐户无权执行您尝试运行的任何内容。

      运行 services.msc 并查看服务的属性。 在登录页面上,作为测试,更改设置,使其使用您的帐户运行服务。如果成功了,你就知道问题出在哪里了。

      要查看的另一件事是服务内部的路径。使用 getenv("PATH") 并查看您可能依赖的路径是否丢失。

      希望这会有所帮助...

      【讨论】:

        【解决方案5】:

        我最终使用了 CreateProcess。到目前为止,它一直在发挥作用。

        【讨论】:

          猜你喜欢
          • 2021-01-30
          • 2011-04-13
          • 2017-03-12
          • 1970-01-01
          • 1970-01-01
          • 2011-07-20
          • 1970-01-01
          • 2011-08-22
          • 2012-09-17
          相关资源
          最近更新 更多