Share via


HOW TO GET FOREGROUND WINDOW

Question

Friday, February 7, 2014 5:09 PM

Hello,

How to get Active/Foreground Window Process Name and Handle in vb.net.

Thanks.

salman

All replies (15)

Saturday, February 8, 2014 12:22 PM âś…Answered

Hi,

 I am not sure if your trying to get the Window Title or the Process`s MainModule FileName but, here is an example that you can try. I used a ListBox on my app to list the info about the window. Of coarse i had to hide my app and use a timer to give a 1 second pause before calling the sub or i got my applications info. You can try using the API function signatures and the Sub in your application and list the info however you want. This like any of the other examples will require Administrator privileges.

Imports System.Runtime.InteropServices
Imports System.Text

Public Class Form1
    <DllImport("user32.dll", EntryPoint:="GetWindowThreadProcessId")> _
    Private Shared Function GetWindowThreadProcessId(<InAttribute()> ByVal hWnd As IntPtr, ByRef lpdwProcessId As Integer) As Integer
    End Function

    <DllImport("user32.dll", EntryPoint:="GetForegroundWindow")> Private Shared Function GetForegroundWindow() As IntPtr
    End Function

    <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> Private Shared Function GetWindowTextLength(ByVal hwnd As IntPtr) As Integer
    End Function

    <DllImport("user32.dll", EntryPoint:="GetWindowTextW")> _
    Private Shared Function GetWindowTextW(<InAttribute()> ByVal hWnd As IntPtr, <OutAttribute(), MarshalAs(UnmanagedType.LPWStr)> ByVal lpString As StringBuilder, ByVal nMaxCount As Integer) As Integer
    End Function


    Private Sub GetForgroundWindowInfo()
        Dim hWnd As IntPtr = GetForegroundWindow()
        If Not hWnd.Equals(IntPtr.Zero) Then

            Dim lgth As Integer = GetWindowTextLength(hWnd)
            Dim wTitle As New System.Text.StringBuilder("", lgth + 1)
            If lgth > 0 Then
                GetWindowTextW(hWnd, wTitle, wTitle.Capacity)
            End If

            Dim wProcID As Integer = Nothing
            GetWindowThreadProcessId(hWnd, wProcID)

            Dim Proc As Process = Process.GetProcessById(wProcID)
            Dim wFileName As String = ""
            Try
                wFileName = Proc.MainModule.FileName
            Catch ex As Exception
                wFileName = ""
            End Try

            ListBox1.Items.Add("Window Handle - " & hWnd.ToString)
            ListBox1.Items.Add("Window Title - " & wTitle.ToString)
            ListBox1.Items.Add("Process Id - " & wProcID.ToString)
            ListBox1.Items.Add("Main Module FileName - " & wFileName.ToString)
        End If
    End Sub
End Class

Here i opened Notepad and ran my app


Friday, February 7, 2014 5:36 PM

Hello,

How to get Active/Foreground Window Process Name and Handle in vb.net.

Thanks.

salman

Option Strict On

Public Class Form1

    Private Declare Function GetTopWindow Lib "user32.dll" (ByVal hwnd As IntPtr) As IntPtr


    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.Text = "Testing"
        Me.CenterToScreen()
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        RichTextBox1.Text = ""
        For Each p As Process In Process.GetProcesses
            'If the MainWindowTitle of the process is not empty   
            If p.MainWindowTitle = String.Empty = False Then
                'Add the process name, the main window title, and the process ID (what windows uses to identify the process) to the RichTextBox)
                If GetTopWindow(p.Handle).ToString <> "0" Then
                    RichTextBox1.AppendText("Top window is " & p.ProcessName & "....." & p.MainWindowTitle & "....." & p.Id & vbCrLf)
                Else
                    RichTextBox1.AppendText("Bottom windows are " & p.ProcessName & "....." & p.MainWindowTitle & "....." & p.Id & vbCrLf)
                End If
            End If
        Next
    End Sub

End Class

Please BEWARE that I have NO EXPERIENCE and NO EXPERTISE and probably onset of DEMENTIA which may affect my answers! Also, I've been told by an expert, that when you post an image it clutters up the thread and mysteriously, over time, the link to the image will somehow become "unstable" or something to that effect. :) I can only surmise that is due to Global Warming of the threads.


Friday, February 7, 2014 6:19 PM

The program is showing "Access is denied" error at the following line: ** If GetTopWindow(p.Handle).ToString <> "0" Then**

salman


Friday, February 7, 2014 6:31 PM

The program is showing "Access is denied" error at the following line: ** If GetTopWindow(p.Handle).ToString <> "0" Then**

salman

Try running the app with admin privileges. Launch visual studio with admin privileges, which it doesn't have just because the logged on user does, and the app will run in debugger with admin privileges.

That also happens when the "Ease of access" On Screen Keyboard is running but running the app with admin privileges resolves that.

Please BEWARE that I have NO EXPERIENCE and NO EXPERTISE and probably onset of DEMENTIA which may affect my answers! Also, I've been told by an expert, that when you post an image it clutters up the thread and mysteriously, over time, the link to the image will somehow become "unstable" or something to that effect. :) I can only surmise that is due to Global Warming of the threads.


Friday, February 7, 2014 8:28 PM

If I understand your question correctly, see if the following works for you:

    <DllImport("user32.dll")> _
    Function GetForegroundWindow() As IntPtr
    End Function

    <DllImport("user32.dll", SetLastError:=True)> _
    Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, <System.Runtime.InteropServices.Out()> ByRef processId As UInteger) As UInteger
    End Function 

   Private Function GetForegroundWindowProcess() As String

        Const nChars As Integer = 256
        Dim Buff As New System.Text.StringBuilder(nChars)
        Dim WindowHandle As IntPtr = 0
        Dim ProcessID As IntPtr = 0

        WindowHandle = GetForegroundWindow()
        GetWindowThreadProcessId(WindowHandle, ProcessID)

        Dim ActiveProcess = Process.GetProcessById(ProcessID)
        Console.WriteLine("Process: " & ActiveProcess.ProcessName)

    End Function

Paul ~~~~ Microsoft MVP (Visual Basic)


Saturday, February 8, 2014 6:12 AM

Dear Pual P,

The output of the code is Process: Idle

I am using Visual Studio 2010 .Net Framework 4, And my account type is administrator.

salman


Saturday, February 8, 2014 1:56 PM | 1 vote

Which OS are you working with? I tested this code under Windows 7 and it works just fine. Which app was the foreground window when the code was executing?

Paul ~~~~ Microsoft MVP (Visual Basic)


Saturday, February 8, 2014 5:41 PM

Dear Pual P,

The output of the code is Process: Idle

I am using Visual Studio 2010 .Net Framework 4, And my account type is administrator.

salman

Did you ever run visual studio with admin privileges before trying any of the codes provided? After all you previously posted that "The program is showing "Access is denied" error at the following line: ** If GetTopWindow(p.Handle).ToString <> "0" Then"** and I told you that if you run visual studio with admin privileges then run your app in debugger it will probably resolve that error.

Do you understand that just because you have an administrator account does not mean visual studio running in your desktop has admin privileges? Therefore no app running in visual studio debugger on your desktop has admin privileges either.

Try right clicking on the Visual Studio shortcut (or whatever you use to launch visual studio) and selecting run as admin in the window that pops up. Then visual studio will run with admin privileges so open your app and run it in debugger where it will have admin privileges too.

And maybe that's why Pauls code isn't working for you either.

Please BEWARE that I have NO EXPERIENCE and NO EXPERTISE and probably onset of DEMENTIA which may affect my answers! Also, I've been told by an expert, that when you post an image it clutters up the thread and mysteriously, over time, the link to the image will somehow become "unstable" or something to that effect. :) I can only surmise that is due to Global Warming of the threads.


Saturday, February 8, 2014 7:39 PM

Uh, yeah this is essentially the same code I posted. Same API function calls, same call to the Process Class. What's up with that?

FYI, Admin privileges are not required.

Paul ~~~~ Microsoft MVP (Visual Basic)


Saturday, February 8, 2014 8:12 PM

Uh, yeah this is essentially the same code I posted. Same API function calls, same call to the Process Class. What's up with that?

FYI, Admin privileges are not required.

Paul ~~~~ Microsoft MVP (Visual Basic)

I tried your code and even with visual studio running with admin privileges it still returned application idle for the On Screen Keyboard which is always on top.

Please BEWARE that I have NO EXPERIENCE and NO EXPERTISE and probably onset of DEMENTIA which may affect my answers! Also, I've been told by an expert, that when you post an image it clutters up the thread and mysteriously, over time, the link to the image will somehow become "unstable" or something to that effect. :) I can only surmise that is due to Global Warming of the threads.


Saturday, February 8, 2014 8:19 PM

Uh, yeah this is essentially the same code I posted. Same API function calls, same call to the Process Class. What's up with that?

FYI, Admin privileges are not required.

Paul ~~~~ Microsoft MVP (Visual Basic)

 Just so you know i did not copy your code. I see you used the same functions but, this is code i wrote a while ago for a program similar to Spy++ that lists all the opened widows on the computer and all the info about them but, not quite as fancy as Spy++. For the Admin privileges, i just took it that they may be required on newer OS`s from what Mr. Monkeyboy was saying about his code. I am on an old XP machine and run as administrator all the time so i don`t know if the newer OS`s need Admin privileges or not but, thanks for pointing it out.


Saturday, February 8, 2014 8:35 PM

 Just so you know i did not copy your code. I see you used the same functions but, this is code i wrote a while ago for a program similar to Spy++ that lists all the opened widows on the computer and all the info about them but, not quite as fancy as Spy++. For the Admin privileges, i just took it that they may be required on newer OS`s from what Mr. Monkeyboy was saying about his code. I am on an old XP machine and run as administrator all the time so i don`t know if the newer OS`s need Admin privileges or not but, thanks for pointing it out.

Yeah, I run into that too sometimes. But I figure if someone posted the same thing or referenced a link I posted it in, then there is no reason for me to post it again. Hey, I'm generally flattered if someone uses my code or even improves it or fixes it. :-)

What I found odd was that one post was an answer and the other wasn't. That can be somewhat confusing and misleading for others reading the thread.

Paul ~~~~ Microsoft MVP (Visual Basic)


Saturday, February 8, 2014 8:42 PM

I tried your code and even with visual studio running with admin privileges it still returned application idle for the On Screen Keyboard which is always on top.

If the process is Idle then it generally means that there is no "active" app. I tested my code by running the app in the background and using a Timer Class to check (like IronRazerz) and repeatedly activated other apps to the foreground. I was never able to get it to return the "Idle" process.

Paul ~~~~ Microsoft MVP (Visual Basic)


Saturday, February 8, 2014 9:27 PM

Yeah, I run into that too sometimes. But I figure if someone posted the same thing or referenced a link I posted it in, then there is no reason for me to post it again. Hey, I'm generally flattered if someone uses my code or even improves it or fixes it. :-)

Paul ~~~~ Microsoft MVP (Visual Basic)

 I posted my version because, i saw you gave a way to get the process name and was not sure if he actually wanted the process name or the full path to the executable that the window belongs to or if he wanted the Title of the window. Sometimes people know what they want but, don`t know the proper words for them. So maybe he didn`t want the process name but, the exe path or the window title. He never did say why he marked mine as an answer.    :)

PS. I just tried your code and being i have Option Strict turned on all the time i had to change a few lines but, it worked for me to get the process name. So again, maybe that isn`t what he wanted.


Wednesday, September 6, 2017 12:14 PM

Thank You, works great!

Cheers