如何使用 MSVC++ 在 Windows 上使用 exec()?

问题描述

我正在尝试将为 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 execUse 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","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 >> output.log) 中@ChrisDodd 在评论中提出的建议。

解决方法

有两件事需要解决:

  1. 'C' 后的冒号 ':' 不应加倍
  2. _execlp 期望参数列表中的空值来检测没有更多参数。

所以这是有效的:

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