wholelottastress
wholelottastress

Reputation: 1

What is the difference between using a win32 function and passing a cmd command through system()?

should i use win32 functions if a terminal command can do the same thing through system();? Like, what is the difference between using a win32 function to, for example, create a file and using system("echo >> file.txt");.

Upvotes: 0

Views: 144

Answers (2)

Ted Lyngmo
Ted Lyngmo

Reputation: 117318

should i use win32 functions if a terminal command can do the same thing through system();?

This asks for opinions, but I'm going out on a limb and say: Almost never use system().

One category of reasons to actually use it is if you need to use a program that doesn't come with a library/API - but it has an understandable commandline interface. I place all usage of system() in the as a last resort bin. It's nearly never what you should aim for.

Like, what is the difference between using a win32 function to, for example, create a file and using system("echo >> file.txt");.

The system() call on Windows and Posix platforms creates a child process (cmd.exe, /bin/sh or whatever shell is the default) to execute the command. The main process then just waits for the child process to finish.

This sub shell has to interpret the command, validate it and print all sorts of meaningless messages to stdout when you as a programmer are usually interested in if creating the file succeeded or not. All this usually takes a lot more system resources than just calling the API at hand.

The shells are also different beasts and come in different versions so your program may behave differently if deployed on different versions of your target platform. This isn't detected at program startup as it would be if your program linked with the proper libraries instead. Different shells have different security vulnerabilities and programs using system() have historically been successfully attacked. Since you probably don't know the version of the shell you use, you also have no control over this part.

That said, I don't recommend calling the WinAPI directly to accomplish what your example does. Using standard C++ should do quite well:

if(std::ofstream os("file.txt", std::ios::app); os) {   // c++17 init-statement
    os << '\n';
} else {
    // failed opening "file.txt" for writing
}

Edit: dxiv pointed out that my suggestion doesn't do what echo >> file.txt does when using cmd.exe as a shell. This would apparently be the equivalent:

    os << "ECHO is on.\n";

As also pointed out by dxiv, this "reinforces both "may behave differently" and "print all sorts of meaningless messages".

Upvotes: 4

Tumbleweed53
Tumbleweed53

Reputation: 1551

system() creates a new instance of the command interpreter (cmd.exe) and runs the specified command in it. There's a substantial overhead to creating a new process, so you should only do so if you absolutely need to. This is a dumb analogy, but it would be like saying, hmm, I need a refrigerator, I'll build a whole house so I can use the fridge.

Furthermore, you'll find that if you use system(), the created process's stdin and stdout are not accessible to your program without further work. So you can't tell much about what it did other than by reading the return code.

Compare that to calling Windows API functions to accomplish your task, which are much faster since they don't have the process creation overhead, provide rich error codes, and on top of that also provide tons and tons more functionality than does cmd.exe.

Upvotes: 2

Related Questions