FindWindowA() 返回 0,当我使用 GetLastError() 检查错误代码时,它也是 0 (ERROR_SUCCESS)

Posted

技术标签:

【中文标题】FindWindowA() 返回 0,当我使用 GetLastError() 检查错误代码时,它也是 0 (ERROR_SUCCESS)【英文标题】:FindWindowA() returns 0 and when i check the error code with GetLastError() it's also 0 (ERROR_SUCCESS) 【发布时间】:2020-04-21 09:05:11 【问题描述】:

这是我正在编写的 dll 注入代码的一部分。 我正在使用FindWindowA() 来获取INJ_PROC_NAME 中定义的窗口进程的HWND。 问题是该函数总是返回 0,当我使用 GetLastError() 检查错误时,它也返回 0。我不知道是什么问题,因为错误代码没有给我关于错误的正确信息。

HWND Hwnd = FindWindowA(NULL, INJ_PROC_NAME);
    if (Hwnd == NULL)
    
        std::cout << "Couldn't find window named \"" << INJ_PROC_NAME << "\": error-"
            << GetLastError() << std::endl;
        getchar();
        return -1;
    

这是输出:

Couldn't find window named "notepad.exe": error-0

这是一个已知问题吗?我无法在 Microsoft 的文档或堆栈溢出中找到有关它的任何信息。我就是想不通这个……

编辑: 显然,当我运行程序时,记事本是打开的。

【问题讨论】:

【参考方案1】:

错误很可能在 std::cout 的某个地方被破坏。

试试这个:

 if (Hwnd == NULL)
    
        DWORD error = GetLastError();  // first thing we retrieve the error

        std::cout << "Couldn't find window named \"" << INJ_PROC_NAME << "\": error-"
            << error << std::endl;
        getchar();
        return -1;
    

无论如何都必须在失败后立即保存错误号。

FindWindow 不成功的真正原因是它不是在寻找进程名称,而是寻找类似于@987654325 的窗口标题 @。

否则,如果FindWindow 没有找到该窗口,则不管 Microsoft 文档如何伪装,最后一个错误实际上都没有设置。

结论

使用FindWindow 可能不是最好的方法,您应该按照in this Microsoft documentation 的描述枚举进程。

【讨论】:

嗨,感谢您的建议,但它仍然提供相同的输出。为什么它会在 std::cout 中被破坏? 请特别注意,尽管调用线程的最后一个错误代码在被发现之前有多次更改的机会 - 观察到的行为是意料之中的:没有具有该窗口名称的窗口。 API返回nullptrGetLastError返回ERROR_SUCCESS表示FindWindow的返回值不是错误的结果。 @IInspectable 您对 MS 文档的解释肯定是正确的。但是OTOH如果你试图打开一个不存在的文件(类似于试图找到一个不存在的窗口),那么这是一个错误。

以上是关于FindWindowA() 返回 0,当我使用 GetLastError() 检查错误代码时,它也是 0 (ERROR_SUCCESS)的主要内容,如果未能解决你的问题,请参考以下文章

关于vb2005中用到的arp函数findwindow无法在user32.dll中找不到findwindowA接口

void main如何返回0?

.format() 在使用 0:g 删除尾随零时返回 ValueError

在函数中使用错误的 networkx 前辈

g++ 错误? (bool_val ? 0 : 1) 既不返回 0 也不返回 1

VB.Net中该怎么调用windows的API?