问题描述
我有一个必须调用 C:\Windows\System32\regedit.exe
的 32 位应用程序,但它运行的是 C:\Windows\SysWOW64\regedit.exe
。如何调用 regedit
中的 System32
?
void CSecureShellView::OnCommandsRegistry64bit()
{
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
CString szExe;
szExe = "regedit.exe";
if (CreateProcess("C:\\Windows\\Sysnative\\cmd.exe",szExe.GetBuffer(100),FALSE,CREATE_NO_WINDOW,&si,&pi))
{
WaitForSingleObject(pi.hProcess,IGNORE);// optionally wait for process to finish
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
}
条件返回 True,但 regedit
不运行。
我放了 SysNative
而不是 System32
,但它不起作用。在 szExe
中,我输入了字符串 "C:\Windows\regedit"
,但它不起作用。等等……
解决方法
您试图通过 regedit.exe
运行 cmd.exe
,为什么?您得到的任何结果都适用于 cmd.exe
,无论它执行什么命令。
只需运行注册表编辑器而不是 cmd.exe
。然而,有一个皱纹。
64 位 C:\Windows\System32
文件夹没有 regedit.exe
可执行文件。 64 位 regedit.exe
位于 C:\Windows
中。如果 32 位进程尝试直接运行该可执行文件,则会运行 32 位 C:\Windows\SysWOW64\regedit.exe
,这是您不想要的。
为了让 32 位进程运行 64 位 regedit.exe
,它需要运行 C:\Windows\Sysnative\Regedt32.exe
,这是一个将运行 64 位 C:\Windows\regedit.exe
的存根:
void CSecureShellView::OnCommandsRegistry64bit()
{
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
CString szExe = "C:\\Windows\\Sysnative\\Regedt32.exe";
if (CreateProcess(NULL,szExe.GetBuffer(),NULL,FALSE,&si,&pi))
{
WaitForSingleObject(pi.hProcess,INFINITE); // optionally wait for process to finish
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
}
如果 CreateProcess()
因 ERROR_ELEVATION_REQUIRED
失败,并且您不想运行提升的 32 位进程,则尝试使用 ShellExecute/Ex()
和 runas"
动词来启动 {{ 1}} 升高。
话虽如此,您不应硬编码 Regedt32.exe
安装文件夹的路径。询问 Windows 实际安装的位置,例如通过 Windows
、GetWindowsDirectory()
、SHGetFolderPath(CSIDL_WINDOWS)
等。然后您可以将 SHGetKnownFolderPath(FOLDERID_Windows)
附加到该路径的末尾。>
为了解决这个问题,我使用了 ShellExecuteEx()
和 SHELLEXECUTEINFO
。
HRESULT result = CoInitializeEx(NULL,COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
SHELLEXECUTEINFO Sei;
ZeroMemory(&Sei,sizeof(SHELLEXECUTEINFO));
Sei.cbSize = sizeof(SHELLEXECUTEINFO);
Sei.lpFile = "C:\\windows\\regedit.exe";
Sei.nShow = SW_SHOW;
Sei.fMask = SEE_MASK_INVOKEIDLIST;
Sei.lpVerb = "open";
ShellExecuteEx(&Sei);
if (result == S_OK || result == S_FALSE)
CoUninitialize();