首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CreateProcess能够执行批处理文件,但是文档显示相反的情况。

CreateProcess能够执行批处理文件,但是文档显示相反的情况。
EN

Stack Overflow用户
提问于 2014-02-04 13:05:24
回答 1查看 2.2K关注 0票数 4

考虑以下文件:

a.bat

代码语言:javascript
复制
@echo Hello from bat %1

c.cpp

代码语言:javascript
复制
#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 他说表示必须这样做:

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

但是,我得到了以下输出:

代码语言:javascript
复制
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

这意味着,每当.bat扩展名在lpApplicationNamelpCommandLine中显式指定时,批处理文件就会成功启动。这也适用于.cmd,但不适用于.vbs。有没有人知道这种行为背后的原因以及实践和文件之间的区别?这种行为是“意外”还是在不同的Windows版本之间持续存在?(我使用Windows 7 HP)文档中有什么地方可以从中推断出这种行为吗?

EN

回答 1

Stack Overflow用户

发布于 2014-02-04 13:36:12

作为一名软件开发人员,您不应该依赖无文档的行为。即使某些东西在测试时运行良好,如果文档中说“您必须以另一种方式来做”,您通常必须忘记您的测试,并按照指示执行。否则,您的软件可能会在下一个windows更新中悄无声息地崩溃,甚至包括一些次要的更新。

现在在批处理/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路径。如果路径或参数包含空格或引号,则对转义适用相同的规则。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21553379

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档