Get Application's Window Handles
You could do what Process.MainWindowHandle
appears to do: use P/Invoke to call the EnumWindows
function, which invokes a callback method for every top-level window in the system.
In your callback, call GetWindowThreadProcessId
, and compare the window's process id with Process.Id
; if the process ids match, add the window handle to a list.
How to get the window handle for a form and its child window handles in c#
I achieved this using couple of functions such as "GetProcessesByName" to get the handle of main window and "EnumChildWindows" to get the handle of child windows.Refer below for source code,
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using Microsoft.Win32;
[DllImport("user32.Dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr parentHandle, Win32Callback callback, IntPtr lParam);
Process[] p = System.Diagnostics.Process.GetProcessesByName("StikyNot"); //this is for sticky notes
foreach (Process p1 in p)
{
IntPtr MainWindowHandle = p1.MainWindowHandle;
List<IntPtr> GetChildWindowsHandle=GetChildWindows(MainWindowHandle);
}
public static List<IntPtr> GetChildWindows(IntPtr parent)
{
List<IntPtr> result = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(result);
try
{
Win32Callback childProc = new Win32Callback(EnumWindow);
EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
}
finally
{
if (listHandle.IsAllocated)
listHandle.Free();
}
return result;
}
How i can get window handle of running programs in windows
you are looking for:
Enumerating processes:
BOOL WINAPI EnumProcesses
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682623(v=vs.85).aspx
an example how to use is in same link
Enumerating windows
BOOL WINAPI EnumWindows
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633497(v=vs.85).aspx
an example how to use it:
How to stop EnumWindows running infinitely win32
Get all window handles for a process
Pass IntPtr.Zero
as hWnd
to get every root window handle in the system.
You can then check the windows' owner process by calling GetWindowThreadProcessId
.
How do I find the window handle for a running process?
This is a challenging task. An application can have any number of top level windows. These can come and go as the application runs.
I see you are using SendKeys - are you writing an automation or test system? If so, you may want to look at the accepted answer to this question.
Could you better explain what you are trying to do? For example, are you working with random applications? Or is the target process something you have control over?
Update
Ok, your extra information means this problem is more tractable. You need to use Spy++, a debugger, or Xperf, Process Explorer, or some other tool to undertand the windowing and threading behavior.
Once you know that, you can then use various Window management functions to find the window you need and deal with it.
Also, be aware of the Windows Integrity Mechanism. The application you use to find windows in another process and send them messages must be at a higher Integrity Level (IL) that the driven application.
How can I determine if, given a window handle, the window handle is part of the Windows UI as opposed to an application?
After some digging, I found this question which references the "GetDesktopWindow()" and "GetShellWindow()" pinvoke functions. Using the GetShellWindow() api and it's pid, I was able to determine the process ID of the windows shell, and compare it to the process ID of the application I was currently moving. Finally, since file explorer windows are part of the explorer process, I checked to see if the window has "File Explorer" as it's title, or if any of it's parent windows do.
[DllImport("user32.dll", SetLastError = false)]
private static extern IntPtr GetShellWindow();
[DllImport("user32.dll", SetLastError = true)]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out IntPtr lpdwProcessId);
public bool IsPartOfWindowsUI
{
get
{
var desktopwindow = new WindowRef(GetShellWindow());
return (desktopwindow.ThreadProcessID == ThreadProcessID &&
//Check to see if title of this window or it's parents are
//Basic file explorer windows
!TitleTree.Contains("File Explorer"));
}
}
C# get window handle after starting a process
If it's the main window you're after, Process.MainWindowHandle
will give you what you need.
Return Window handle by it's name / title
Update: See Richard's Answer for a more elegant approach.
Don't forget you're declaring you hWnd
inside the loop - which means it's only visible inside the loop. What happens if the window title doesn't exist? If you want to do it with a for
you should declare it outside your loop, set it inside the loop then return it...
IntPtr hWnd = IntPtr.Zero;
foreach (Process pList in Process.GetProcesses())
{
if (pList.MainWindowTitle.Contains(wName))
{
hWnd = pList.MainWindowHandle;
}
}
return hWnd; //Should contain the handle but may be zero if the title doesn't match
Or in a more LINQ-y way....
IntPtr? handle = Process
.GetProcesses()
.SingleOrDefault(x => x.MainWindowTitle.Contains(wName))
?.Handle;
return handle.HasValue ? handle.Value : IntPtr.Zero
Related Topics
How to Center Your Main Window in Wpf
How to Put Text on Progressbar
Automatically Rename a File If It Already Exists in Windows Way
How to Dynamically Switch Web Service Addresses in .Net Without a Recompile
Detect Windows Font Size (100%, 125%, and 150%)
Should I Transform Entity (Persistent) Objects to Dto Objects
Check If an Executable Exists in the Windows Path
Edit Specific Element in Xdocument
How to Add an Item to a Listbox in C# and Winforms
Threadpool Not Starting New Thread Instantly
Resharper Complains When Method Can Be Static, But Isn'T
Webdriver How to Wait Until the Element Is Clickable in Webdriver C#
Serilog Mssql Sink Doesn't Write Logs to Database
How to Intercept Console Output
Alternative to Multiple String.Replaces