首页 > 解决方案 > 调用 Wow64GetThreadContext 返回错误“当文件已存在时,无法创建文件”。

问题描述

我在 32 位进程上使用从 64 位进程调用的 Wow64GetThreadContext。我正在用这种方法捕捉WOW64 上下文结构。

MSDN 似乎不再提供此方法的文档,但在GetThreadContext文档页面上仍然引用了它。我不确定这是为什么。由于文档不可用,我很难弄清楚为什么会出现以下错误。

抛出错误的代码如下。当我检查 GetLastWin32Error 时抛出的错误是:When the file already exists, the file cannot be created.

有谁知道为什么会抛出这个错误?我根本没有创建一个让我感到困惑的文件。

ContextWow = new WOW_CONTEXT();
ContextWow.ContextFlags = CONTEXT_FLAGS.CONTEXT_ALL;
try
{
    Wow64GetThreadContext(ThreadHandle, ref ContextWow);
    if (new Win32Exception(Marshal.GetLastWin32Error()).Message != "The operation completed successfully")
    {
        throw new Exception("Win32 Exception encountered when attempting to get thread context" + new Win32Exception(Marshal.GetLastWin32Error()).Message);
    }
}

标签: winapi

解决方案


这是您想要的文档的链接,由 Internet 档案馆于 2019 年 7 月 10 日捕获:

Wow64GetThreadContext()功能

根据文档:

返回值

如果函数成功,则返回值非零。

如果函数失败,则返回值为零。要获取扩展错误信息,请调用 GetLastError。

您的错误处理是错误的。它相当于执行以下操作:

ContextWow = new WOW_CONTEXT();
ContextWow.ContextFlags = CONTEXT_FLAGS.CONTEXT_ALL;
try
{
    Wow64GetThreadContext(ThreadHandle, ref ContextWow);
    if (Marshal.GetLastWin32Error() != 0)
    {
        throw new Exception("Win32 Exception encountered when attempting to get thread context" + new Win32Exception().Message);
    }
}

你犯了一个非常常见的错误,GetLastError()那就是在错误的时间打电话。正如文档所说,Win32 错误代码只有在返回 false 时才有效Wow64GetThreadContext(),您没有检查它。

您所做的不是检查错误的正确方法(获取错误代码或对其进行比较)。正确的代码应该更像下面这样:

ContextWow = new WOW_CONTEXT();
ContextWow.ContextFlags = CONTEXT_FLAGS.CONTEXT_ALL;

if (!Wow64GetThreadContext(ThreadHandle, ref ContextWow))
{
    throw new Exception("Error encountered when attempting to get thread context", new Win32Exception());
}

话虽这么说,您看到的错误消息"When the file already exists, the file cannot be created",是您系统的ERROR_ALREADY_EXISTS(183) 错误代码文本,这不是Wow64GetThreadContext()记录为报告失败的错误代码,实际上对于这种类型没有多大意义报告故障的功能。所以,最有可能发生的事情Wow64GetThreadContext()实际上是返回 true,但是由于您没有正确检查失败,您实际上会看到来自早期/内部 API 调用的错误代码,该代码在Wow64GetThreadContext()返回 true 时没有被覆盖,所以它在这种情况下应该忽略,而不是采取行动。


推荐阅读