I try to get the managed control from a shown Word Application window using following code:
Process[] processes = null;
processes = Process.GetProcessesByName("WINWORD");
Process wordProc = processes[0];
Control wordControl = Control.FromHandle(wordProc.MainWindowHandle);
unfortunately wordControl is always null... as far as i know, FromHandle returns null, if no handle related control was found. But actually I guess there should be a related control, because I can see the window on my screen.
Therefore my question is, if I'm doing something terribly wrong while trying to get the handle or the control.
Or maybe my general approach will not work for some, at this time unknown, reasons based somewhere in the .NET / Windows environment.
What you are trying to do is not possible. You cannot take an instance of Word running in its own process and cast it as a C# WinForms Control - this would be totally insecure.
Depending on what you want to do, there are two approaches you can take:
If you want to affect the behaviour of an existing Word instance, then you can send it some messages using SendMessage() and other assorted User32.DLL functions. Use Pinvoke / DLL Import to accomplish this.
If you are trying to use Word functionality in an app you have written (e.g. create word document) then use Word interop libraries:
Edit
If you're interested in handling key events in an existing Word instance, you can use a Low Level keyboard hook to deal with key events, specifying the handle of the word procs you're interested in.
Control.FromHandle requires you to pass the handle of the managed control, not the MainWindowHandle of the win32 window...
Related
I was playing around with Microsoft Spy++ and noticed that not only does it find the open processes, but can find the individual components running in each process. For example there is this application that allows you to open a window in which there is a textbox for an IP address and textbox for a port. Spy++ can detect these components. Knowing that Spy++ can detect them, is there anyway possible to find them in a separate c# application and go on to MODIFY their contents and otherwise interact with the program? (such as firing a click event on a button)
This is feasible. Try use PInvoke (InterOp) or AutomationElement, or AutomationPeer (for WPF applications) to automate all you wish to do.
Also you might wish to try Inspect and UISpy application as well.
Automation elements/peer is a non-intrusive mechanism to control UI using accessibility framework. One of the weaknesses in windows is its lack of defence against code injection. Put simply:
As a privileged user,
- You can Open and Modify a running Process image
- Make it load your OWN DLL
- Make it run your OWN thread (that potentially listens to commands from your process) and
- allows you to read any bits of memory you want.
Look at detours (http://research.microsoft.com/en-us/projects/detours/) for how to do it with Managed Processes.. Unfortunately, Microsoft removed the inject at runtime features.
Also look at http://msdn.microsoft.com/en-us/magazine/cc163617.aspx for doing things in the managed world (Apps like Snoop utilise that)
I have an application that I am trying to automate on Windows. I need to find the location of a window that is running inside the application, and then automate a couple of mouse events on the application.
In a previous incarnation of the software that I am automating, I was able to search for child windows of the process which were named using the GetWindowText WinAPI function from C# (in combination with GetWindowTextLength).
The software manufacturers have now updated the software and updated the way that the child windows are drawn. Now each window lacks a caption, and has a class name of QWidget. I can no longer use my old strategy to find the child window location. I presume the use of QWidget means the windowing system uses the Qt framework.
Is there any way of pulling any data from the QWidget using PInvoke that I might be able to identify my windows with?
There's a couple problems here. One is that you can't get "unshared" data from another process. You can get at window data by pinvoking methods like GetWindowLong; but unless you know specific data about what QWidget does in that data (the other problem), there's not much you can do with the data.
Another problem is if you want to use most QT objects in a managed application (you can do this with C++/CLI and IJW) you need to initialize A QT Application object in your application... I'm not sure how this would impact what you want to do.
We have an old Windows 32 bit app written in C++ which does some stuff and displays the results in what resembles a textbox.
I have been ask to write an application in C# that reads the data out of the old app and then further process the data.
The issue is how do I read the textbox in the old application?
Someone told me I can get the “handle “of the application using windows API and step through the controls and then read each ones data! Is this true and if so how would I do it from C#?
This is to be a .Net 4 Windows forms Application.
Many thanks
You're probably going to have to use some Interop calls to accomplish this, specifically using a combination of FindWindow / FindWindowEx and SendMessage & WM_GETTEXT / WM_GETTEXTLENGTH.
Here is an article on the subject (in c++, however the same concepts will just need to be ported to use P/Invoke), it's a bit dated but I believe is should be very relevant to your situation.
You can use Spy++ application (comes with VisualStudio) to inspect your native application and find class name of control you are looking for.
Having that, you can get your native application's main window handle, which is easy if you are responsible for launching that application from your c# app:
...
var proc = Process.Start();
var mainWndHandle = proc.MainWindowHandle;
Otherwise, you will have to find other means of finding that window, fe. you can use function that I've described below to look for that window on your desktop (see msdn page for more info)
If you have all that, you can then get handle to the textbox control, using FindWindowEx function (as well as you can use it to find main window, by passing NULL as a hwndParent).
And when you have handle to this textbox, you can read it contents, by sending message of WM_GETTEXT.
If you haven't been PInvoke'ing much, you can check http://pinvoke.net/ for reference on how to call WINAPI function from your c# program.
Do you really need the UI of the C++ application? Because it will be very unconfortable to have 2 separate UIs with different message pumps. You'll need to syncronize this mess on the update of the value.
Why don't you properly strip the logic code from the C++ application and expose it in a Interop CLR project (C++/CLI)? If you don't need to add more features to the C++ app, it seems very straightforward to me
I need to see the component type, meaning the name of the class that was programmed, of a clicked control in another process. I need the type so I can react to the clicked control and then do some Automation tasks.
Right now I am doing the following:
1. I FindWindow() from Win32 to find the main window handle of the process.
2. Then, I get call EnumChildWindows(), also from Win32, and get the window handles of all the children of the main window handle.
3. Now it gets tricky. When I call GetClassName(), it returns WindowsForms10.STATIC.app [...] since the controls I am trying to read are custom.
How can I get the type of the clicked control using the window handles from EnumChildWindows() ? Is what I am trying to do even possible?
I have been looking into using SendMessage() from Win32 to the process but it seems that there is no system defined message that could help.
I'm afraid that it's not possible. A handle just refers to internal data of the window that Windows needs. There is no information beyond that available.
You can get the class name, but it is neither standardized nor unique. Most controls that are not basic-functionality controls like buttons, lists, etc. are derived from a very primitive one, namely "Static". But again, there's no information about the high-level WinForms control available.
This leads to the fact that, even if you knew the type, you cannot just cast the pointer/handle, because there no data behind it.
Can you somehow restate your problem? Maybe use Remote Procedure Calls? Does it work without the high-level WinForms objects? Things like clicking, moving or renaming work with plain Win32 API.
I want to create a program or use a program that will read the memory values out of another application. Does anyone know of an application/library that will do this?
The target app is this. I would like to read the exchange rate values from it.
I'm an experienced c# programmer, but have never worked with the Win32/user32 api which is what I'm assuming I'll have to deal with to pull this off.
Any help that gets me going in the right direction is greatly appreciated.
Update:
I managed to use Spy++ to get the window handle, so I'm sure I can get the values some how.
Have you looked into AutoIT or AutoHotKey?
Both of these open source options have well documented abilities to read text from application windows (and send keystrokes or mouseclicks to them).
AutoIT is very easy to use and well documented.
An example of reading text from a window would be:
$text = WinGetText("title of window", "")
MsgBox(0, "Text read was:", $text)
This can be compiled into an executable.
Typically an application creates controls in a dialog in a consistent manor, same ID, same order etc, so finding a control programatically is fairly simple. Using Spy++ find the control's ID and then you can search the windows created by the application for the desired control. Not being familiar with the app in question I cannot give specifics, but if Spy++ shows the value you desire, it is likely not difficult to obtain the value in your code.
What type of control is the value displayed in? You'll may be able to use GetDlgItemText to obtain the value once you have the parent window handle and control ID? To get the parent window try using EnumWindows.
It might be easier to scrape their data by automating a screenshot and then ocr process. If that's your goal.
Potentially relevant links:
get-a-screenshot-of-a-specific-application
ocr-with-the-tesseract-interface
May be this article helps - http://msdn.microsoft.com/en-us/magazine/cc163617.aspx, but I think it's not universal and for your task is better to get access directly to Forex API/Web-Service or try to catch needed data on network.
It is possible to screen-scrap things created with native windows controls; if that is the case, you should be able to see the controls using Spy++. But some times controls are implemented "by hand", and there is no way to screen-scrap them (e.g. some Java graphic toolkits play directly with the graphics, so everything day do is meaningless from the outside, or even some Office menus are implemented without using the menu control).
The Windows accessibility API is a possible way to screen-scrap the values; check if "Narrator", the screen reader that comes with windows, is able to read aloud your target application.