【问题标题】:Hide console in C system() function, Win在 C system() 函数中隐藏控制台,Win
【发布时间】:2010-12-08 12:16:22
【问题描述】:

我正在用 Dev-C++ 编写一个 C 程序,我需要使用几个 Windows (CMD) 命令。很简单,但是执行system()函数中的命令时,程序在执行中运行控制台。

一个例子:

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

    int main()
    {
      system("if not exist c:\my_docs\doc.txt (xcopy /Y doc.txt c:\my_docs\)"); // Cmd command
      system("pause");
      return 0;
    }

是否存在其他功能,或修改后不显示控制台?

谢谢!最好的问候。

【问题讨论】:

  • Dev C++ 已过时,我强烈建议您选择其他的
  • 如果没有显示控制台窗口,您希望“暂停”命令如何工作? cmd.exe 也是一个控制台应用程序 - 没有简单的方法可以阻止控制台窗口显示。
  • @Larry Osterman,很高兴在 SO Larry 上见到你;我喜欢这个博客!
  • 天哪,Dev-C++ 的最后一个稳定版本是 2005 年......它有点过时了,是的。 +1 山姆。
  • 是的拉里,我也想过这个,但是问是免费的,而且stackoverflow中没有类似的问题;-)

标签: c windows cmd system


【解决方案1】:
int win_system(const char *command)
{
    // Windows has a system() function which works, but it opens a command prompt window.
    
    char            *tmp_command, *cmd_exe_path;
    int         ret_val;
    size_t          len;
    PROCESS_INFORMATION process_info = {0};
    STARTUPINFOA        startup_info = {0};

    
    len = strlen(command);
    tmp_command = malloc(len + 4);
    tmp_command[0] = 0x2F; // '/'
    tmp_command[1] = 0x63; // 'c'
    tmp_command[2] = 0x20; // <space>;
    memcpy(tmp_command + 3, command, len + 1);
    
    startup_info.cb = sizeof(STARTUPINFOA);
    cmd_exe_path = getenv("COMSPEC");
    _flushall();  // required for Windows system() calls, probably a good idea here too
    
    if (CreateProcessA(cmd_exe_path, tmp_command, NULL, NULL, 0, CREATE_NO_WINDOW, NULL, NULL, &startup_info, &process_info)) {
        WaitForSingleObject(process_info.hProcess, INFINITE);
        GetExitCodeProcess(process_info.hProcess, &ret_val);
        CloseHandle(process_info.hProcess);
        CloseHandle(process_info.hThread);
    }
    
    free((void *) tmp_command);
    
    return(ret_val);
}

【讨论】:

  • 您能否在您的代码块中加入一些解释/评论?
  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
【解决方案2】:

注意:我的回答不一定是针对您的具体问题量身定制的,但此问答是“没有命令提示符的 Windows 系统”和其他类似查询的顶部 Google result

这是一种无需新的cmd.exe 窗口即可执行命令的方法。基于Roland Rabien's answerMSDN,我写了一个工作函数。

#include "AtlBase.h"
#include "AtlConv.h"
  int windows_system(const char *cmd) {
    PROCESS_INFORMATION p_info;
    STARTUPINFO s_info;
    DWORD ReturnValue;
    CA2T programpath(cmd);

    memset(&s_info, 0, sizeof(s_info));
    memset(&p_info, 0, sizeof(p_info));
    s_info.cb = sizeof(s_info);

    if (CreateProcess(programpath, NULL, NULL, NULL, 0, 0, NULL, NULL, &s_info, &p_info)) {
      WaitForSingleObject(p_info.hProcess, INFINITE);
      GetExitCodeProcess(p_info.hProcess, &ReturnValue);
      CloseHandle(p_info.hProcess);
      CloseHandle(p_info.hThread);
    }
    return ReturnValue;
  }

适用于所有 Windows 平台。像您一样拨打电话system()

【讨论】:

  • 我正在使用 MinGW,我得到了fatal error: AtlBase.h: No such file or directory
  • 什么是 AtlBase.h 和 AtlConv.h?
【解决方案3】:

您可以使用WinExec("your cmd command", SW_HIDE); 代替system("cmd command")

【讨论】:

  • 谢谢。我是 16 位 Windows 的时代,但忘记了这个功能。它在 WIndows LogOn(Cred.Provider DLL) 的一个重要场景中派上用场,其中 MS 不允许 CreateProcess(),并且 system() 在后面有一个控制台窗口(因此使它不是一个有吸引力的选项)。谢谢你!
  • 在我的代码中是system("chcp 936")。正在设置 cosole 显示汉字。如果我在另一个应用程序中运行它,那将是徒劳的。
【解决方案4】:

正如 FigBug 所说,CreateProcess() 是要走的路,但我不认为 CreateProcess() 可以执行 shell if 语句。您可能需要将类似这样的内容作为命令传递:

"cmd.exe /c \"if not exist c:\my_docs\doc.txt (xcopy /Y doc.txt c:\my_docs\)\""

但更好的解决方案可能是使用CreateFile() 测试文件是否存在并使用CopyFile() 复制它。

【讨论】:

    【解决方案5】:

    您可以使用 CreateProcess 来完成。

    STARTUPINFOW si;
    PROCESS_INFORMATION pi;
    
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));
    
    if (CreateProcessW(command, arg, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
    {
        WaitForSingleObject(pi.hProcess, INFINITE);
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }
    

    【讨论】:

    • +1 谢谢,我会测试一下。这不是我想要的,但它是一个很好的答案。
    • 我在 windows 7 中尝试了您的代码,但它不起作用。我想执行 adb shell am broadcast -a NotifyServiceStart。顺便说一下,我已经将adb添加到PATH中,system()可以很好的运行这一行。
    • msdn.microsoft.com/en-ca/library/windows/desktop/… "该字符串可以指定要执行的模块的完整路径和文件名,也可以指定部分名称。在部分名称的情况下,函数使用当前驱动器和当前目录以完成指定。该函数将不使用搜索路径。此参数必须包含文件扩展名;假定没有默认扩展名。"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-21
    • 1970-01-01
    • 2011-04-20
    • 2018-12-01
    • 1970-01-01
    相关资源
    最近更新 更多