【问题标题】:AppHangB1 trying to bring an Outlook.Explorer to the foreAppHangB1 试图让 Outlook.Explorer 脱颖而出
【发布时间】:2018-07-21 00:15:21
【问题描述】:

我们有一个在某些情况下可能会启动 Outlook 的应用程序。它获取一个 Outlook.Explorer 对象 (oWindow As Outlook.Explorer) 并调用其 .Activate() 过程。

到目前为止,一切都是 hunky dory,但是我想把 Explorer 对象带到前台,我们称之为这个过程:

Public Shared Sub BringToFore(ByVal oWindow As Object)

    Dim oFoo As IOleWindow
    Dim hWnd As IntPtr

    oFoo = TryCast(oWindow, IOleWindow)
    If Not (oFoo Is Nothing) Then
        Try
            oFoo.GetWindow(hWnd)
        Catch ex As Exception

        End Try
    End If

    Try
        If hWnd.ToInt32 <> IntPtr.Zero.ToInt32 Then
            Try
                If IsIconic(hWnd) Then
                    ShowWindow(hWnd, SW_RESTORE)
                End If
                SetForegroundWindow(hWnd)
            Catch ex As System.Exception

            End Try
        Else

        End If

    Catch ex As Exception

    End Try

End Sub

IOleWindow 定义如下:

<ComImport(), Guid("00000114-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
Private Interface IOleWindow
    ''' <summary>
    ''' Returns the window handle to one of the windows participating in in-place activation
    ''' (frame, document, parent, or in-place object window).
    ''' </summary>
    ''' <param name="phwnd">Pointer to where to return the window handle.</param>
    Sub GetWindow(<System.Runtime.InteropServices.Out()> ByRef phwnd As IntPtr)

    ''' <summary>
    ''' Determines whether context-sensitive help mode should be entered during an
    ''' in-place activation session.
    ''' </summary>
    ''' <param name="fEnterMode"><c>true</c> if help mode should be entered;
    ''' <c>false</c> if it should be exited.</param>
    Sub ContextSensitiveHelp(<[In](), MarshalAs(UnmanagedType.Bool)> ByVal fEnterMode As Boolean)
End Interface

以及通常的声明

Private Const SW_RESTORE As Integer = 9
Private Declare Auto Function IsIconic Lib "user32" (ByVal hWnd As IntPtr) As Boolean
Private Declare Auto Function SetForegroundWindow Lib "user32" (ByVal hwnd As IntPtr) As Long
Private Declare Auto Function ShowWindow Lib "user32" (ByVal hWnd As IntPtr, ByVal nCmdShow As Integer) As IntPtr

BringToFore 过程在大多数情况下都能正常工作。有时调用应用程序 - WPF 应用程序 - 只是挂起。事件查看器记录 AppHangB1 并且应用程序崩溃。

我可以在 BringToFore 程序中做些什么来防止这种情况发生吗?知道其中哪些是导致问题的原因吗? TryCast(oWindow, IOleWindow), oFoo.GetWindow(hWnd), IsIconic(hWnd), ShowWindow(hWnd, SW_RESTORE) 还是 SetForegroundWindow(hWnd)? (老实说,我个人怀疑它可能是 SetForegroundWindow)。如果是这样,我可以在代码中做些什么吗?有什么条件要检查?如果 this 条件为真,那么不要尝试做 that ..... 之类的事情?我宁愿不要放弃将 Explorer 设置为前台的想法。在这种情况下,Outlook 可能会出现在我的应用程序“后面”,而一些用户可能只是没有意识到发生了一些事情......如果你发现我的想法。

谢谢

皮诺

【问题讨论】:

    标签: vb.net visual-studio outlook


    【解决方案1】:

    如果窗口属于活动进程以外的进程,Windows 会阻止您使用SetForegroundWindow。您需要先致电AttachThreadInput。这是函数(Delphi):

    function ForceForegroundWindow(hWnd: THandle): BOOL;
    var
      hCurWnd: THandle;
    begin
      hCurWnd := GetForegroundWindow;
      AttachThreadInput(
        GetWindowThreadProcessId(hCurWnd, nil),
        GetCurrentThreadId, True);
      Result := SetForegroundWindow(hWnd);
      AttachThreadInput(
        GetWindowThreadProcessId(hCurWnd, nil),
        GetCurrentThreadId, False);
    end;
    

    【讨论】:

    • 您好 Dmitry - 抱歉回复晚了;我休年假了!这听起来确实很有希望,我会进行同样的调查。问候
    • 好吧,我按照建议实现了 AttachThreadInput,到目前为止,在我自己的系统上以调试模式运行它仍然完美运行。现在我将不得不在客户的机器上尝试同样的事情......但这看起来很有希望!谢谢德米特里!
    • 只是一个问题.... 为什么这不会总是失败?相反,它似乎大部分时间都可以工作,但偶尔会因可怕的 AppHangB1 错误而失败? Anyhoooooooo.... 现在将在现场进行测试。
    • 经过进一步测试,当 Outlook 启动显示对话框时,它似乎会发生;这可能是为 ClickYes 编写的“程序正在尝试访问”对话框,或者是“服务器不可用等待/重试/取消”对话框,甚至是在 Outlook.Application 创建并使其可见时弹出的提醒。我现在已经将这个功能移植到一个独立于主 UI 线程的线程中。到目前为止,它看起来不错。但是,我保留了您的 AttachThreadInput,因为无论如何这似乎是个好主意。
    【解决方案2】:

    我认为这个问题需要更多的调试。几年前我发现here 发布了一个类似的问题,其中提出了一个可能有助于找到根本原因的建议。

    【讨论】:

    • 感谢 Joshg345,但我不确定场景是否匹配。根据我们的用户的说法,我们的应用程序自动关闭,而不是因为她试图按照您的线程中的建议关闭它。页面上的建议链接似乎已失效,但我会去搜索 Windbg
    • ok google 确实是我们的朋友,我发现了更多 Windbg 的最新链接。谢谢乔什
    猜你喜欢
    • 1970-01-01
    • 2012-03-17
    • 1970-01-01
    • 2023-03-09
    • 2011-01-30
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    相关资源
    最近更新 更多