我在执行命令行时遇到一个非常奇怪的问题。下面的代码运行没有问题:
ShellExecute(NULL, "open", "cmd.exe", "/C ipconfig > file_output.txt", NULL, SW_SHOWNORMAL);
执行时,ipconfig输出被写入file_output.txt”,这正是我想要的。但是当我使用bcdedit时:
ShellExecute(NULL, "open", "cmd.exe", "/C bcdedit > file_output.txt", NULL, SW_SHOWNORMAL);
文件已生成,但文件中没有任何内容。我可以以管理员身份在 cmd.exe 中执行相同的命令并且它有效。我也尝试过:
ShellExecute(NULL, "open", "cmd.exe", "/C bcdedit /enum all > file_output.txt", NULL, SW_SHOWNORMAL);
bcdedit 不起作用。没有错误。以下是我尝试过的其他一些方法:
再次,在 cmd.exe 中执行相同的命令可以工作,但在我的代码中似乎不起作用。我已经搜索了一整天,但似乎找不到有用的东西。有什么想法吗?
编辑:经过进一步调试,现在我使用命令看到以下内容。
“bcdedit”不被识别为内部或外部命令、可操作程序或批处理文件。
“C:\Windows\System32 cdedit.exe”未被识别为内部或外部 c 命令、可运行的程序或批处理文件。
我再次尝试了上面列出的所有 4 种方法,但显然仍然无法将其识别为命令。 **bcdedit.exe 实际上存在于 C:\Windows\System32** 中。
这就是在 64 位 Windows 上运行的 32 位进程的文件系统重定向的效果。
在 64 位 Windows 上,每当 32 位应用程序尝试访问
%windir%\System32
目录时,访问将被重定向到 %windir%\SysWOW64
。这个过程对于应用程序来说是透明的,并且它仍然认为它正在访问 %windir%\System32
目录。
因此,当您的 32 位应用程序调用
cmd.exe
时,它实际上是在调用驻留在 cmd.exe
中的 32 位版本的 %windir%\SysWOW64
。 32 位版本的 cmd.exe
依次尝试从 bcdedit.exe
目录调用 SysWOW64
,但 bcdedit.exe
中不存在 32 位版本的 %windir%\SysWOW64
,它仅存在于 %windir%\System32
中, 32位cmd.exe
无法访问。
要获取有关 文件系统重定向器 的更多信息,您可以参考 MSDN 页面 https://msdn.microsoft.com/en-us/library/windows/desktop/aa384187(v=vs.85).aspx
解决此问题的最便捷方法是将应用程序编译为 64 位可执行文件,以便在 64 位 Windows 上运行。
但是,如果您有特定需要将应用程序保留为 32 位,或者您希望有一个可以在 32 位和 64 位系统上运行的单个可执行文件,那么您可以暂时禁用文件系统重定向器在 64 位 Windows 上运行 64 位版本的
cmd.exe
。有关如何执行此操作的信息可以在上面发布的链接中找到。
但通常不建议这样做,它需要通过对主题的理解,并且有可能产生比解决的问题更多的问题。
如果需要针对 32 位和 64 位 Windows 的单个可执行文件,则另一种方法是生成应用程序的 32 位和 64 位版本,并将 64 位可执行文件嵌入到 32 位版本中作为资源。然后,32 位应用程序可以检测它是在 32 位还是 64 位 Windows 下运行,因此它要么继续运行,要么将 64 位可执行文件提取到临时位置来运行它。
好的。我认为您的应用程序正在以管理员身份运行,但
ShellExecute
命令不是。 为此,我相信您需要将第二个参数改为 runas
而不是 open
。像这样:
ShellExecute(NULL, "runas", "cmd.exe", "/C bcdedit > file_output.txt", NULL, SW_SHOWNORMAL);
确保您使用的是 64 位编译器。我设法重新创建了这个问题,但似乎它在 32 位上不起作用,也直接使用 bcdedit 而不使用任何完整路径。这就像一个司机。 x86 驱动程序不适用于 x64 等。此外,如果您使用 32 位,则使用 32 位编译器。