It’s common that user will call CreateProcess() or ShellExecute() in order to execute external program from visual C++ project. But what make both different in term of security? ShellExecute() is powerful but extremely dangerous API function. It’s virtually anything can be executed with this API function. In fact, if we try to pass a non-executable file to ShellExecute(), the API will search the registry looking for the right application to launch the file. Imagine if hacker  modified a file extension and that file being executed by using ShellExecute() API, this may causing your program to end up doing something completely unexpected and potentially disastrous.
The safest way to execute an external program  is to use CreateProcess(). The most important arguments for the purposes of proper secure use of this API are lpApplicationName and lpCommandLine. lpApplicationName Name of the program to execute.  This argument may also be specified as NULL, in which case the program to execute is determined from the lpCommandLine argument. lpCommandLine Any command-line arguments to pass to the external program. If there are no arguments to pass, this argument may be specified as NULL. If lpApplicationName is specified as NULL, the program to execute is taken from lpCommandLine. Therefore, both lpApplicationName and lpCommandLine cannot be NULL.