【问题标题】:Delphi - Wow64EnableWow64FsRedirection Error 32-bit OSDelphi - Wow64EnableWow64FsRedirection 错误 32 位操作系统
【发布时间】:2018-02-21 22:39:38
【问题描述】:

我有一个代码示例。

unit Unit1;

interface

uses
...

type
...

function Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection: BOOL): BOOL; stdcall;

var
...

implementation

{$R *.dfm}

uses
...

function Wow64EnableWow64FsRedirection; external kernel32 name 'Wow64EnableWow64FsRedirection';

procedure LaunchOSK;
begin
  Wow64EnableWow64FsRedirection(False);
  try
    ShellExecute(0, 'OPEN', PChar('osk.exe'), nil, nil, SW_SHOWNORMAL);
  finally
    Wow64EnableWow64FsRedirection(True);
  end;
end;

end.

此代码在 64 位操作系统中运行良好。但是,当您尝试在 32 位操作系统 (XP) 中使用它时,自然会收到一条错误消息(过程入口点 Wow64Enable64FsRedirection 无法位于动态链接库 kernel32.dll 中。) .如果您隔离 Wow64EnableWow64FsRedirection 并运行 ShellExecute,它会正常启动。

在过去的 2 天里,我一直在尝试我在 Google 上搜索过的不同的东西,但在安全地启动 32 位和 64 位 OSK 的情况下,我没有一个作品。即使是著名的 Delphi 大师的建议也不起作用。

我不需要关于禁用 Wow64EnableWow64FsRedirection 的讲座。既然是暂时的,就没有伤害没有犯规。

我需要了解如何获取此代码并隔离 Wow64Enable64FsRedirection 接口过程及其随附的实现部分以及例如当应用程序在 XP 上运行时 LaunchOSK 过程的必要部分。这可能吗???编译器语句没用,对吧?

如果这是不可能的,那么我将不得不求助于生产 2 个应用程序(一个用于 XP,另一个用于 64 位),这是最后的手段。

提前致谢。

【问题讨论】:

  • 不错的尝试,维多利亚。将布尔值更改为布尔值。还为实现功能添加了“延迟”。应用程序现在开始正常。但是,当我启动 OSK 时,我收到“外部异常 C06D007F”错误。那好吧。启动过程中的 Wow64EnableWow64FsRedirection 代码也需要隔离。我想我可以测试 64 位操作系统。
  • 不仅是位数。您还需要测试操作系统版本。或者您可以使用动态加载而不是延迟加载。
  • 完成了。使用 64 位测试。其余代码完好无损。谢谢。最简单的解决方案总是最好的。就授予您胜利而言,您删除的评论是它,而不是您给出的答案。不知道如何根据评论奖励。
  • 将代码编辑为最​​终更改,以防万一有人需要。
  • 我在回答中也是这么说的。有一个关于错误参数类型的额外说明。但正如我所说,仅测试位数是不够的。你可以有64位的Windows XP,不会有这样的功能。

标签: delphi


【解决方案1】:

您可以使用dynamic loading 并简单地检查GetProcAddress 函数是否返回有效的函数地址。

或者您可以使用delayed loading 并仅在操作系统版本和位数符合必要要求时调用导入的函数。

【讨论】:

  • 只包含指向场外位置的链接的答案在这里是不合适的(你已经知道了,我敢肯定)。接受不会改变事情。抱歉,我的 DV 是因为您的答案中没有相关内容。站外链接应仅用作附加参考,而不应用作主要(或仅在这种情况下)内容。
  • @Ken,然后不考虑链接。答案仍然是使用延迟加载。或动态加载。 可以轻松找到有关该主题的必要信息。
  • 不考虑链接。重新考虑你的答案。 :-) 来自How do I write a good answer?鼓励链接到外部资源,但请在链接周围添加上下文,以便您的其他用户知道它是什么以及为什么会出现。始终引用重要链接中最相关的部分,以防目标站点无法访问或永久离线。
  • 在“延迟加载”的情况下,您可以分配一个失败挂钩,该挂钩返回一个指向不执行任何操作的回退函数的指针,那么您根本不需要测试操作系统版本。正常调用函数,它要么调用真正的OS函数,要么调用fallback函数。
  • @Remy,真的。那可以更好。我应该把它包含在这篇文章中吗?
【解决方案2】:

您的代码使用加载时间链接。导入的函数必须存在于系统中,否则您的可执行文件将无法启动。

相反,您需要使用运行时链接。使用LoadLibraryGetProcAddress 链接到函数。如果GetProcAddress 找不到该函数,则它不可用,当然您不需要调用它,因为您使用的是 32 位操作系统。

不过,正确的做法是生成一个 64 位进程,然后该进程可以启动 OSK 进程。如果您确实需要禁用重定向,请注意告诉您使用Wow64DisableWow64FsRedirection 的文档。

最后,最好使用CreateProcess 来启动进程。涉及 shell 和文件关联没有任何好处。既然可以直接调用CreateProcess,为什么还要让shell调用呢?

好的,这通常是个好建议,但再次强调,OSK 很特别。见Delphi - On Screen Keyboard (osk.exe) works on Win32 but fails on Win64

【讨论】:

  • "正确的方法是生成一个 64 位进程,然后可以启动 OSK 进程" - osk.exe 位于 %windir%\System32%windir%\SysWow64 文件夹。您不必为了运行 OSK 而生成 64 位进程。您甚至根本不需要弄乱 FS 重定向器,只需运行 %windir\system32\osk.exe 并让 Windows 选择适当的 OSK 版本。当然,如果要强制运行原生版本,那就有条件地在Wow64进程中运行%windir%\SysNative\osk.exe,在非Wow64进程中运行%windir%\System32\osk.exe
  • @Remy,我从这个页面 forums.embarcadero.com/thread.jspa?messageID=670677 尝试了你的代码。在 GetWindowsDirectory 上遇到访问冲突。我正在使用东京。
  • @Remy,我有一个在 W7 64 位上运行的 32 位应用程序。根据我所阅读的内容,我提到的内容中不承认 sysnative。太糟糕了。
  • @ZtecSoftwareLLC:这不是在其他站点提出问题的联系点。如果您对该站点上发布的代码有疑问,请在那里询问。在完全不同的网站上让他们谈论完全不同的主题是不合适的,尤其是在这个网站上。
猜你喜欢
  • 1970-01-01
  • 2013-08-29
  • 2011-02-20
  • 1970-01-01
  • 2015-09-26
  • 2013-10-31
  • 1970-01-01
  • 2011-12-18
  • 2011-07-06
相关资源
最近更新 更多