CreateProcess能够执行批处理文件,但文档却相反

时间:2014-02-04 13:05:24

标签: windows batch-file createprocess

考虑以下文件:

a.bat

@echo Hello from bat %1

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

请注意,我没有在cmd.exe的任何电话中指定CreateProcess,而我必须执行MSDN says

  

要运行批处理文件,必须启动命令解释程序;将lpApplicationName设置为cmd.exe并将lpCommandLine设置为以下参数:/ c加上批处理文件的名称。

但是,我得到以下输出:

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

这意味着,只要在.batlpApplicationName中明确指定lpCommandLine扩展名,就会成功启动批处理文件。这也适用于.cmd,但不适用于.vbs。有谁知道这种行为背后的原因以及练习和文档之间的区别?这种行为是“意外”还是在不同的Windows版本中持续存在? (我使用的是Windows 7 HP)文档中是否有任何一点可以推断出这种行为?

1 个答案:

答案 0 :(得分:0)

作为软件开发人员,您不应该依赖未记录的行为。即使在测试它时工作正常,如果文档说“你必须以另一种方式做”,你通常必须忘记测试,并按照指示行事。否则,您的软件可能会在下一次Windows更新时无声地崩溃,甚至包括次要更新。

现在在batch / vbs文件上。

要运行CMD / BAT,请调用GetEnvironmentVariable("ComSpec")以获取cmd.exe的路径,然后调用CreateProcess指定command = cmd.exe,参数/C path_to_CMD_file arg1 arg2。 如果路径或参数包含空格,则必须将它们包含在引号中。如果路径或参数包含包含"的空格,请替换为^"

要运行VBS,请调用ExpandEnvironmentStrings("%windir%\\System32\\cscript.exe")或wscript.exe,然后在.exe文件的第一个参数中传递VBS路径。如果路径或参数包含空格或引号,则相同的规则适用于转义。