【问题标题】:Visual Studio 2010 hangs when I debug method AttachThreadInput()当我调试方法 AttachThreadInput() 时,Visual Studio 2010 挂起
【发布时间】:2011-12-25 21:50:05
【问题描述】:

我有 Visual Studio 2010 Ultimate SP1,我的项目基于 MFC。

当我调试项目的下一个代码时,Visual Studio 挂起:

CWnd* _window = CWnd::FromHandle(_hwnd_);
if (_window) {
    DWORD nForeThread, nAppThread;

    nForeThread = ::GetWindowThreadProcessId(::GetForegroundWindow(), 0);
    nAppThread = GetCurrentThreadId();

    if (nForeThread != nAppThread)
    {
        AttachThreadInput(nForeThread, nAppThread, TRUE);
        _window->BringWindowToTop();
        _window->ShowWindow(SW_RESTORE);
        AttachThreadInput(nForeThread, nAppThread, FALSE);
    }
    else
    {
        _window->BringWindowToTop();
        _window->ShowWindow(SW_RESTORE);
    }
}

我在下一行有一个断点:

    AttachThreadInput(nForeThread, nAppThread, TRUE);

所以如果我按下 F10 或 F11 或 F5 按钮,那么 VS 会立即挂起。

可能是什么问题?

【问题讨论】:

  • 首先,你不要检查返回码,AttachThreadInput 可能会失败,你应该经常检查。其次,我的猜测是 VS2010(您将附加到您的线程的线程)所做的事情与此调用或您的输入事件处理不兼容。
  • 调用AttachThreadInput后无法获取返回值,VS挂了...
  • 关于后者,很可能是。那请问怎么办?
  • 你必须想一想你想要完成什么,看看是否有其他方法可以做到。
  • 我这样做了。我排除了调试模式的代码(#ifndef _DEBUG)。但是问题没有解决!

标签: c++ visual-studio-2010 debugging mfc freeze


【解决方案1】:

我怀疑您只是在不了解后果的情况下从某个地方复制了此代码。这是我在 2005 年讨论过的 Five Things Every Win32 Programmer Should Know 之一。

AttachThreadInput的意思是“请把这两个线程的钱全部拿出来放在一个共同的银行账户里,这样两个线程都不能取钱,除非两个线程一起去银行取钱。”

如果两个线程已婚或同一个家庭成员或以其他方式通过共享银行帐户相互信任,这很好,并且还可以协调他们的行动,以便当其中一个线程需要钱时,它可以调用另一个线程然后说“嘿,你能和我一起去银行吗?我需要一些钱。”

在你的情况下,你说:“请把我所有的钱和所有街上随便走来的人的钱都存入一个联名银行账户,这样我和除非我们俩一起去银行取钱,否则其他人可以提取任何钱。”

这对您和对方来说都是个坏主意,因为您现在无法提取任何资金,除非您设法与对方取得联系。但是因为你随便抓了一个走在街上的人,你不知道他的手机号码,所以你没有办法联系他说“嘿,你能和我一起去银行吗?”那个随机的人现在可以访问你所有的银行账户信息。 (你的钱和那个人的钱混在一起了——不再是“你的钱”和“那个人的钱”了。只是一堆钱。)

将“银行账户”改为“输入队列”,将“钱”改为“输入”,将“去银行”改为“查询消息队列”。

在您的情况下,您所做的是抓住 Visual Studio 并说“好的,我们现在有一个联名银行账户!”现在看看会发生什么:Visual Studio 无法提取任何资金,因为它需要您去银行。但是你不能去银行,因为你被破解了调试器。结果:没有人得到任何钱。

您的设计存在根本缺陷。你需要重新审视你的情况。

另请参阅:I warned you: The dangers of attaching input queues

【讨论】:

  • 这是 C# 的 System.Windows.Forms.Control 的 InvokeRequired BeginInvoke/Invoke 结束的地方吗?
  • @CS 我不确定您在哪里看到任何连接。如果您有问题,请提出一个新问题,不要征用现有问题。
  • 这是一个多余的比喻。它几乎不能解释问题。看起来像是在讲故事。
  • @Raymond Chen 我已经阅读了一堆关于为什么 AttachThread 会挂起的材料,但很多人仍在使用(像我一样,使用语音输入到 Process.Start/ShellExecute 来打开/带来应用程序/窗口到前台)来解决合法的用户友好需求,包括一个应用程序将另一个应用程序带到前台并赋予它焦点。我希望有一些官方的、批准的、记录在案的(带有示例)的方法,这样我们就不必使用 AttachThread hack。
  • @Kevin 我认为如果你声明你的进程是 UIAccess,那么就会授予全面的权限来窃取前景。
猜你喜欢
  • 2016-02-21
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 2012-07-19
  • 1970-01-01
  • 1970-01-01
  • 2023-02-13
相关资源
最近更新 更多