How can I get the window class name of a certain process?
I want to achieve this in c#.
I've tried the process class in c# but I can only get the window name of the process.
Thanks
I assume you mean you want to get the class name of the main window of a process.
To do this, you will need to get the handle to the main window using the MainWindowHandle of your Process object, and then use the following interop method to obtain the class name:
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
see pinvoke.net for sample code and MSDN for details on the function.
You can also use the windows ui automation framework to achieve this without getting into pinvoke.
int pidToSearch = 316;
//Init a condition indicating that you want to search by process id.
var condition = new PropertyCondition(AutomationElementIdentifiers.ProcessIdProperty,
pidToSearch);
//Find the automation element matching the criteria
AutomationElement element = AutomationElement.RootElement.FindFirst(
TreeScope.Children, condition);
//get the classname
var className = element.Current.ClassName;
Related
Is unity standalone player for Windows a Windows.Form? If so, how can we access its handle?
if(Form.ActiveForm != null)
{
m_form = Form.ActiveForm;
Debug.Log("m_form.Name");
}
I am using the Mono version of System.Windows.Forms.dll. I am trying the above code to access the Form handle but it always returns null even when window is active, which makes me doubt that standalone windows build is not a Windows.Form.
I basically need to access the toolbar so that I can change its color (Not title, for title we already have a workaround that doesn't require accessing the Form instance). Also, I need to set minimum size for the window. Any solution will be helpful.
You can always p/invoke winapi , so in order to get the handle of the current active window use this :
[DllImport("user32.dll")]
static extern IntPtr GetActiveWindow();
And in order to move / adjust the position of the window u can use one of these :
SetWindowPos, MoveWindow and AdjustWindowRectEx
and btw to get a the window's handle ..
[DllImport("user32.dll", EntryPoint="FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
or :
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
I'm running a small tool (on Windows 7, 32 Bit) that I would like to see what document is open in another application I've tried this, which works for NotePad on Windows.
var myProcess = Process.GetProcessesByName("NotePad");
string title = myProcess[0].MainWindowTitle;
MessageBox.Show(title);
the output is:
"New Text Document - Notepad"
Now, if I try another application it doesn't always give me the correct title but I noticed that most microsoft applications seem to be fine - NotePad, WordPad, EXCEL etc. It's this other software that is an issue. It has a long title but just returns a very simple name.
Here's what I get from my application which has processName = "FooBar"
The actual running window has this up the top:
"FooBar Software Verson 1.2 - [Results]"
and my code gives:
"FooBar"
any ideas?
[EDIT} 2012-11-19
The very crux of this issue is that I was trying to get the name of the open file from the window. It now seems that the software I'm using doesn't display it there. What I've discovered is that a program called "AutoIT3 Window Spy" can get the text I need as the text of the open file is on the window and not only in the title. I downloaded the source (it's part of http://www.autohotkey.com/ which is open source. It seems to rely on many of the suggestions already made but I'm not able to figure it out just yet.) The source code that I"m looking at is c++ and is located here https://github.com/AutoHotkey/AutoHotkey
So I think the solution to my problem may lay elsewhere. This one may go unanswered.
The main window title is what you see when you go in to task manager and look at the Description column, not the window title itself.
It's the title of the process, not the title of a particular window in the process. A given process may have any number of windows open at one time.
If you need the actual window title, you have to hook user32 something like this:
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Security;
namespace Application
{
public class Program
{
public static void Main ( )
{
IntPtr hwnd = UnsafeNativeMethods.FindWindow("Notepad", null);
StringBuilder stringBuilder = new StringBuilder(256);
UnsafeNativeMethods.GetWindowText(hwnd, stringBuilder, stringBuilder.Capacity);
Console.WriteLine(stringBuilder.ToString());
}
}
[SuppressUnmanagedCodeSecurity]
internal static class UnsafeNativeMethods
{
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern int GetWindowText ( IntPtr hWnd, [Out] StringBuilder lpString, int nMaxCount );
[DllImport("user32.dll", SetLastError = true)]
internal static extern IntPtr FindWindow ( string lpClassName, string lpWindowName );
}
}
It's possible that the 'title' you're seeing is some kind of owner-drawn UI element which is overriding the visual representation of the title, while the Windows APIs are likely to ignore that sort of thing.
I'd recommend examining the window with a tool like Spy++ to see if that's the case.
It's also possible that the author of the application decided to override the WM_GETTEXT message and is returning that instead of what's actually in the titlebar, although I'm not 100% sure if GetWindowText() is being called here and whether or not it sends the message explicitly or works some other way.
The developer has stated the following:
"I think the failure may be due to a discontinued property Form.Caption in VB 6.0 that was replaced with a Form.Text in. NET"
Thank you all for your valuable suggestions along the way!
This old stackoverflow post is asking pretty much the same question that I have, however using Spy++ I have obtained the controls handle ID. Now what? :)
I am not sure what this process is called where I can obtain the contents of another applications control from a .net application, therefore I am not having much success with results on the old google machine.
I have an MFC application with a listbox that contains data I need to automate a task using a WPF C# application. I would prefer not to use an external lib and don't think it would be too labour intensive once I have found the process and have my C# app take visibility of the respective list control to do what I need.
Can anyone please point me in the right direction as to what I should be looking up or provide some code to get me started. At this point I'm stuck and my little project relies pretty heavily on this. I don't want to use an OCR either.
Thanks,
Ash
To get text from Win32 ListBox control you have to use messages and functions specially for that control, here is a reference :
http://msdn.microsoft.com/en-us/library/windows/desktop/ff485971%28v=vs.85%29.aspx
In your case you should first see how many items are in the listbox with LB_GETCOUNT, and then for each item get text with LB_GETTEXT.
Here is the method that will return items in a list, parameter is ListBox control window handle :
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, StringBuilder lParam);
const int LB_GETCOUNT = 0x018B;
const int LB_GETTEXT = 0x0189;
private List<string> GetListBoxContents(IntPtr listBoxHwnd)
{
int cnt = (int)SendMessage(listBoxHwnd, LB_GETCOUNT, IntPtr.Zero, null);
List<string> listBoxContent = new List<string>();
for (int i = 0; i < cnt; i++)
{
StringBuilder sb = new StringBuilder(256);
IntPtr getText = SendMessage(listBoxHwnd, LB_GETTEXT, (IntPtr)i, sb);
listBoxContent.Add(sb.ToString());
}
return listBoxContent;
}
This question's answer should get you started. Google P/Invoke and FindWindow() / GetWindowText() family of methods.
Hope that helps.
Windows 7 comes with several built-in themes. They can be accessed by right-clicking the desktop and choosing Personalize. Under Personalize, there is a section names "Aero Themes" containing themes like "Architecture" "Nature" and so on.
I tried using uxtheme.dll's GetCurrentThemeName, but it's actually giving the style name:
"C:\Windows\resources\Themes\Aero\Aero.msstyles" unless my current theme is set to Windows Basic, in which case it returns an empty string. Is there an API that actually returns the theme name, like "Nature" "Architecture" etc...?
The code I tried is as follows:
[DllImport("uxtheme", ExactSpelling = true, CharSet = CharSet.Unicode)]
public extern static Int32 GetCurrentThemeName(StringBuilder stringThemeName,
int lengthThemeName, StringBuilder stringColorName, int lengthColorName,
StringBuilder stringSizeName, int lengthSizeName);
StringBuilder stringThemeName = new StringBuilder(260);
StringBuilder stringColorName = new StringBuilder(260);
StringBuilder stringSizeName = new StringBuilder(260);
Int32 s = GetCurrentThemeName(stringThemeName, 260,stringColorName, 260,stringSizeName, 260);
After taking a look at the MSDN documentation it looks like GetThemeDocumentationProperty might be what you are looking for.
You'll want to use it in conjunction with the theme file (which you alreayd have found in the registry) as well as by passing in the SZ_THDOCPROP_DISPLAYNAME as the second parameter of the method.
In addition here is a site that has the c# method wrapper for the p/invoke call: http://www.java2s.com/Open-Source/CSharp/2.6.4-mono-.net-core/System.Windows.Forms/System/Windows/Forms/VisualStyles/UXTheme.cs.htm
Hope that helps.
My application is something like the Spy++ application: i want to be able to automatically retreive all the different controls of the active window (any application) and their children, and for each control i want to know the type, the name, and the value (caption or text).
I am using a C# windows app.
what is the solution to iterate all the controls of the foreground window and their children (and so on) and retrieve name, type and value?
To enumerate top level windows use EnumWindows(), to get their child windows use EnumChildWindows().
Using theHWNDs from the enumeration, a top level window with a title bars value can be read via GetWindowText(), for other windows you can use the WM_GETTEXT message, or depending on exactly what you want, a message specific to the windows class such as LB_GETTEXT for a listbox.
RealGetWindowClass() will give you the windows class.
Window API reference; http://msdn.microsoft.com/en-us/library/ff468919%28v=VS.85%29.aspx
There are a number of Win32 API functions you can use to write your own Spy++ program. This link explains how to write a Spy++ clone in Visual Basic. I know, you probably don't use Visual Basic, but this document does show you how to duplicate Spy++ using the Win32 API. It should not require much effort to translate this to C#.
Yes you will have to use the windows API if its a window thats not part of your current application. This will get you the currently active window:
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text;
public class MainClass
// Declare external functions.
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
public static void Main() {
int chars = 256;
StringBuilder buff = new StringBuilder(chars);
// Obtain the handle of the active window.
IntPtr handle = GetForegroundWindow();
// Update the controls.
if (GetWindowText(handle, buff, chars) > 0)
{
Console.WriteLine(buff.ToString());
Console.WriteLine(handle.ToString());
}
}
}
It uses the GetWindowText() function to find the name of the window, so I assume it shouldn't be a problem to find out other properties of the windows such as its controls etc.