Delphi中Wow64EnableWow64FsRedirection在32位XP系统报错求助
解决Delphi代码兼容32位XP与64位系统启动OSK的问题
这个问题的核心原因很明确:Wow64DisableWow64FsRedirection 和 Wow64RevertWow64FsRedirection 这两个API只存在于64位Windows系统的kernel32.dll中,32位XP系统根本没有这些函数入口点。如果你的代码是静态引用这些API的,程序在32位XP启动时就会直接报错。
要实现跨系统兼容,正确的做法是动态加载这些API,只在64位系统中调用它们,32位系统直接跳过重定向逻辑,直接用ShellExecute启动OSK。下面是完整的Delphi实现代码:
type // 定义重定向相关函数的类型 TWow64DisableWow64FsRedirection = function(var OldValue: Pointer): BOOL; stdcall; TWow64RevertWow64FsRedirection = function(OldValue: Pointer): BOOL; stdcall; procedure StartOnScreenKeyboard; var hKernel32: THandle; DisableRedir: TWow64DisableWow64FsRedirection; RevertRedir: TWow64RevertWow64FsRedirection; OldRedirState: Pointer; begin // 动态加载kernel32.dll hKernel32 := LoadLibrary('kernel32.dll'); try // 获取两个重定向函数的地址 @DisableRedir := GetProcAddress(hKernel32, 'Wow64DisableWow64FsRedirection'); @RevertRedir := GetProcAddress(hKernel32, 'Wow64RevertWow64FsRedirection'); if Assigned(DisableRedir) then begin // 函数存在,说明当前是64位系统,先禁用文件系统重定向 if DisableRedir(OldRedirState) then try // 启动OSK,此时能正确访问64位系统的System32目录下的osk.exe ShellExecute(0, nil, 'osk.exe', nil, nil, SW_SHOWNORMAL); finally // 必须恢复重定向,避免影响后续操作 if Assigned(RevertRedir) then RevertRedir(OldRedirState); end; end else begin // 函数不存在,说明是32位系统(比如XP),直接启动OSK ShellExecute(0, nil, 'osk.exe', nil, nil, SW_SHOWNORMAL); end; finally // 释放加载的库 FreeLibrary(hKernel32); end; end;
关键细节说明
- 动态加载API:通过
LoadLibrary和GetProcAddress获取函数地址,避免了静态引用导致的程序启动失败——32位XP系统中这些函数不存在,GetProcAddress会返回nil,程序会自动走32位分支。 - 重定向的必要性:在64位系统中,32位进程访问
System32目录会被自动重定向到SysWOW64,而64位的osk.exe只在System32下,所以必须禁用重定向才能正确启动它。 - 安全恢复重定向:用
try...finally包裹重定向恢复逻辑,确保无论ShellExecute是否成功,都能恢复系统的重定向状态,避免影响其他文件操作。
测试验证
- 在32位XP系统中运行:程序会直接跳过重定向逻辑,用
ShellExecute正常启动OSK。 - 在64位Windows系统(Win7/10/11等)中运行:会先禁用重定向,启动正确的64位OSK,然后恢复重定向状态。
内容的提问来源于stack exchange,提问作者user9393481
相关产品推荐
相关产品推荐

