【问题标题】:How to use exec() on Windows with MSVC++?如何在带有 MSVC++ 的 Windows 上使用 exec()?
【发布时间】:2021-07-20 06:14:56
【问题描述】:

我正在尝试将针对 POSIX 编写的 Fortran-C 代码移植到 Windows。据我所知,大部分程序都可以在 Windows 上编译,只需要更改一些小命令。

在程序的fortran部分,有一行

call system("exec xmrcc >> output.log")

问题是,windows 没有任何exec 命令。但是,经过一番挖掘,我发现在 linux 上,exec 命令使用底层的execvp() 调用。在 Windows 上,MSVC++ 提供了_exec() 和相关函数系列。 _execlp() 或 _execlpe() 似乎是我想要的。

所以,我想用 C 函数替换 fortran 系统调用,该函数将环绕 execlpe() 并调用程序 xmrcc.exe。

但是,我无法弄清楚这些功能是如何工作的!我读过Microsoft documentation on exec、Use of execl (Arguments) 和C- Using exec() in windows。在遵循链接的最后一个问题的接受答案后,我编写了这段 C 代码来测试 _execlp()

#include <stdio.h>
#include <windows.h>
#include <process.h>

int main()
{
    printf("started running");
    _execlp("C::\\WINDOWS\\SYSTEM32\\CMD.EXE", "cmd.exe", "/c",
 "echo", "foo",">G:\\Python\\foo.txt");
}

但是,在运行编译后的代码时,我只得到了“开始运行”的输出,然后它返回了; G:\Python 中没有 foo.txt 文件。然后我想可能是输出重定向引起了问题,所以我删除了它:

    _execlp("C::\\WINDOWS\\SYSTEM32\\CMD.EXE", "cmd.exe", "/c", "echo", "foo");

还是什么都没有。它只打印“开始运行”,不打印“foo”。

我有两个主要问题:

  1. 如何在 Windows 上正确运行 _execlp()?(运行 xmrcc.exe 并将输出定向到日志)
  2. 是否必须使用_execlpe() 来传递环境变量?(我不明白这是怎么回事。)

我正在使用 Microsoft Visual C++ v19 编译器。

[请不要提及 cygwin、mingw 或 WSL,它们不是我要找的。而且我知道不鼓励使用fortran中的系统调用,但程序不是我写的,我只是在移植它。

而且我需要使用_execlp(),因为它完全用子进程替换了调用进程,并且最接近linux的exec命令。这是必要的,因为程序的其他部分使用 PIDS,因此必须不产生具有不同 PID 的子进程。]

编辑:删除 exec shell 命令会起作用吗?如call system("xmrcc &gt;&gt; output.log) @ChrisDodd 在 cmets 中建议的。

【问题讨论】:

  • 这里的exec 是内置的exec shell,而不是exec系统调用(系统调用与系统库函数无关)。你可以通过删除它来做同样的事情——例如使用system("xmrcc &gt;&gt; output.log")
  • 使用CreateProcess。
  • @IInspectable CreateProcess() 是否处理 PID?我需要 PID 保持不变。
  • @ChrisDodd 我知道 exec 是 shell 命令。如果我只是删除它,它不会创建一个新进程吗?我认为 exec 命令完全用子进程替换了调用进程,即当 xmrcc 结束时,shell 不会返回。
  • CreateProcess 返回 - 其中包括 - 创建的进程的 PID。尽管 PID 在很大程度上是无用的,因为您无法知道任何给定值是否仍然指代同一进程。这不足为奇,因为在一个比 POSIX 试图捕获的(基本上是 60 年代的技术)先进得多的操作系统的上下文中,大多数 POSIX 的东西都相当无用。

标签: c windows visual-c++ porting


【解决方案1】:

有两件事需要解决:

  1. “C”后面的冒号“:”不能加倍
  2. _execlp 期望参数列表中为 null 以检测没有更多参数。

所以这行得通:

_execlp("C:\\WINDOWS\\SYSTEM32\\cmd.EXE", "cmd.exe", "/c", "echo", "baz", "&gt;c:\\test\\bar.txt", nullptr);

【讨论】:

  • 另外,我需要传递环境变量吗?程序运行需要它们吗?
  • 如果使用_execlp,则无法单独传递环境变量。子进程会继承启动进程的环境变量。
猜你喜欢
  • 2019-04-21
  • 1970-01-01
  • 2011-01-17
  • 1970-01-01
  • 2013-09-11
  • 2015-06-23
  • 2013-07-03
  • 1970-01-01
  • 2019-10-10
相关资源
最近更新 更多