Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hide console in C system() function, Win

I am coding a C program in Dev-C++, and I need to use a couple of Windows (CMD) commands. It is easy, but when the command in the system() function is executed, the program runs the console in the execution.

An example:

#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;
    }

Exists other function, or a modification that do not shows the console?

Thanks you! Best regards.

like image 269
a0rtega Avatar asked Oct 20 '09 21:10

a0rtega


5 Answers

You can use WinExec("your cmd command", SW_HIDE); instead of system("cmd command").

like image 193
Sergio Madrazo Avatar answered Oct 11 '22 09:10

Sergio Madrazo


You can do it with 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);
}
like image 27
Roland Rabien Avatar answered Oct 11 '22 11:10

Roland Rabien


As FigBug stated, CreateProcess() is the way to go, but I don't think that CreateProcess() can execute a shell if statement. You may need to pass it something like this as a command:

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

But a better solution might be to use CreateFile() to test if a file exists and CopyFile() to copy it.

like image 40
Ferruccio Avatar answered Oct 11 '22 10:10

Ferruccio


NOTE: My answer is not necessarily tailored to your specific question, but this Q&A is the top Google result for "Windows system without command prompt" and other similar queries.

Here's a way to execute commands without a new cmd.exe window. Based on Roland Rabien's answer and MSDN, I've written a working function.

#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;
  }

Works on all Windows platforms. Call just like you would system().

like image 43
MD XF Avatar answered Oct 11 '22 09:10

MD XF


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);
}
like image 45
Matt Stead Avatar answered Oct 11 '22 10:10

Matt Stead