CreateProcess is able to execute batch files, but documentation says the opposite

元气小坏坏 提交于 2019-12-23 16:37:36

问题


Consider the following files:

a.bat:

@echo Hello from bat %1

and c.cpp:

#define UNICODE
#include <windows.h>
#include <stdio.h>

void check(TCHAR *cmd, TCHAR *args) {
  STARTUPINFO sinf;
  PROCESS_INFORMATION pinf;
  memset(&sinf, 0, sizeof sinf);
  sinf.cb = sizeof(sinf);

  CreateProcess(cmd, args, NULL, NULL, FALSE, 0, NULL, NULL, &sinf, &pinf);
  WaitForSingleObject(pinf.hProcess, INFINITE);
}

int main() {
  TCHAR cmd1[] = L"a";
  TCHAR cmd2[] = L"a.bat";
  TCHAR cmdargs1[] = L"a argument";
  TCHAR cmdargs2[] = L"a.bat argument";
  TCHAR args[] = L"argument";

  #define run_check(a, b) printf(#a " + " #b "\n"); fflush(stdout); check(a, b)
  run_check(cmd1, cmdargs1);
  run_check(cmd1, cmdargs2);
  run_check(cmd1, args);

  run_check(cmd2, cmdargs1);
  run_check(cmd2, cmdargs2);
  run_check(cmd2, args);

  run_check(NULL, cmdargs1);
  run_check(NULL, cmdargs2);
  printf("Done\n");
  return 0;
}

Note that I haven't specified cmd.exe in any of calls to CreateProcess, while MSDN says that I have to do it:

To run a batch file, you must start the command interpreter; set lpApplicationName to cmd.exe and set lpCommandLine to the following arguments: /c plus the name of the batch file.

However, I get the following output:

cmd1 + cmdargs1
cmd1 + cmdargs2
cmd1 + args
cmd2 + cmdargs1
  Hello from bat argument
cmd2 + cmdargs2
  Hello from bat argument
cmd2 + args
"argument" не является внутренней или внешней
командой, исполняемой программой или пакетным файлом.
NULL + cmdargs1
NULL + cmdargs2
  Hello from bat argument
Done

This means that whenever .bat extension is explicitly specified either in lpApplicationName or lpCommandLine, batch file is successfully started. This works wit .cmd too, but not with .vbs. Does anyone know reason behind such behavior and difference between practice and documentation? Is such behavior 'an accident' or it persists among different Windows versions? (I use Windows 7 HP) Is there any point in documentation from which one can infer such behavior?


回答1:


As a software developer, you shouldn’t rely on undocumented behavior. Even if something works fine when you test it, if the documentation says “you must do it another way”, you generally have to forget your tests, and do as instructed. Otherwise your software can silently break down with the next windows update, including even the minor update.

Now on the batch/vbs files.

To run the CMD/BAT, call GetEnvironmentVariable("ComSpec") to obtain path to cmd.exe, then call CreateProcess specifying command=cmd.exe, arguments /C path_to_CMD_file arg1 arg2. If the path or arguments contain space, you must include them in quotes. If the path or arguments contain spaces contain ", replace with ^".

To run VBS, call ExpandEnvironmentStrings("%windir%\\System32\\cscript.exe") or wscript.exe, then pass VBS path in the first argument of the .exe file. If the path or an argument contain spaces or quotes, same rules apply to escaping.



来源:https://stackoverflow.com/questions/21553379/createprocess-is-able-to-execute-batch-files-but-documentation-says-the-opposit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!