none
GetWindowThreadProcessID returning zero when Vb.net code is passing handle from Excel object RRS feed

  • Question

  • Fellow Coders,

    I have some Script Tasks in SSIS that are using Vs 2015

    I am running these on Widnows Server 2012 r2.

    The vb Excel interop code works fine but I want to add an additional hook that, if needed, I can tell it to kill Excel if it hangs open too long after the official MS cleanup code is run. I know that is not a great idea but I want this option in there, if needed.

    When I pass the handle of my Excel object to GetWindowThreadProcessID, it always returns zero.

    What am I missing. My ID is admin to the box.

    Thanks MG.


    • Edited by mg101 Wednesday, May 15, 2019 5:24 PM spelling
    Wednesday, May 15, 2019 5:24 PM

Answers

  • Are you passing the right window handle ?

    A quick test works :

    Dim xlApp As New Excel.Application
    Dim nProcessId As Integer = 0
    GetWindowThreadProcessId(CType(xlApp.Hwnd, IntPtr), nProcessId)

        <DllImport("User32.dll", SetLastError:=True)>
        Public Shared Function GetWindowThreadProcessId(hWnd As IntPtr, ByRef lpdwProcessId As Integer) As UInteger
        End Function

    • Marked as answer by mg101 Friday, May 17, 2019 11:30 AM
    Wednesday, May 15, 2019 6:10 PM

All replies

  • Are you passing the right window handle ?

    A quick test works :

    Dim xlApp As New Excel.Application
    Dim nProcessId As Integer = 0
    GetWindowThreadProcessId(CType(xlApp.Hwnd, IntPtr), nProcessId)

        <DllImport("User32.dll", SetLastError:=True)>
        Public Shared Function GetWindowThreadProcessId(hWnd As IntPtr, ByRef lpdwProcessId As Integer) As UInteger
        End Function

    • Marked as answer by mg101 Friday, May 17, 2019 11:30 AM
    Wednesday, May 15, 2019 6:10 PM
  • HI Castorix

    Yep.  Almost identical to yours. FYI, this runs perfectly on VS 2008 and and old Windows 2008 Server box.

    My declare :

     Private Declare Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hwnd As IntPtr, _
             ByRef lpdwProcessId As Integer) As Integer

    My code:

    Dim myExcelHwnd As Integer

    myExcelHwnd = myExcel.Hwnd   -- myExcel is a New Excel.Application

    Dim XLProcID As Integer = 0

    GetWindowThreadProcessId(myExcelHwnd, XLProcID)

    Dim XLProc As Process = Process.GetProcessById(XLProcID)

    The xlPROCID contains a zero. there are no errors being raised.

    MG

    Wednesday, May 15, 2019 6:44 PM
  • With DllImport and SetLastError:=True

    Marshal.GetLastWin32Error() returns an error if there is a problem.

    For example, if I force a wrong window handle, it returns 1400 (ERROR_INVALID_WINDOW_HANDLE)

    Wednesday, May 15, 2019 7:08 PM
  • Castorix,

    I have entered the below right below my Class assignment in place of what I have.

    <DllImport("user32.dll", SetLastError:=True)> _
    Private Shared Function GetWindowThreadProcessId(ByVal hwnd As IntPtr, _
                              ByRef lpdwProcessId As Integer) As Integer
    End Function

    testing --


    • Edited by mg101 Wednesday, May 15, 2019 7:54 PM wrding
    • Marked as answer by mg101 Friday, May 17, 2019 11:29 AM
    • Unmarked as answer by mg101 Friday, May 17, 2019 11:30 AM
    Wednesday, May 15, 2019 7:45 PM
  • Add at beginning

    Imports System.Runtime.InteropServices

    (in VS 2015, the Tooltip on the error with "Show potential fixes" does it automatically)

    Wednesday, May 15, 2019 7:56 PM
  • Thanks Castorix

    Figured it out about 5 min ago.

    There is an error. I did get

    • 1400      (ERROR_INVALID_WINDOW_HANDLE)'

    Wednesday, May 15, 2019 8:03 PM
  • In my test, if I check the window handle, I get XLMAIN

    Dim xlApp As New Excel.Application
    Dim hWndExcel As IntPtr
    hWndExcel = CType(xlApp.Hwnd, IntPtr)
    If (hWndExcel <> IntPtr.Zero) Then
        Dim sbWindowClass As StringBuilder = New StringBuilder(128)
        GetClassName(hWndExcel, sbWindowClass, 128)
        MessageBox.Show("Class name = " + sbWindowClass.ToString(), "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
    End If

    <DllImport("User32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
    Public Shared Function GetClassName(ByVal hWnd As IntPtr, ByVal lpClassName As StringBuilder, ByVal nMaxCount As Integer) As Integer
    End Function

    Wednesday, May 15, 2019 8:37 PM
  • HI Castorix,

    Solved it.  I realized that I had issues a Quite Excel before I ran GetWindowThreadProcessId.  Even though I captured the thread id at the beginning of my code, when I run the GWTP command the thread was killed and it would be an invalid one.

    Sorry for the trouble but thanks for your info anyway.

    MG

    Thursday, May 16, 2019 10:55 AM
  • Hi,

    I am glad you have got your solution,please mark the useful replies as answers.

    Best Regards,

    Alex


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, May 17, 2019 7:29 AM
    Moderator