Detecting button enable in another application - c#

I have an application that I would like to write an automated test for. The automated test will mimic an Operator's usage of the application. I cannot change the source code of the application as it is "frozen" for review.
The application will display a pop-up (message) window informing the operator to click on a button after measurements are finished. The button is enabled some time after the message window is closed.
I need to know how to detect when the application enables this button. My research so far indicates that the application should broadcast a custom message to help the automated testing; but I cannot modify the source code.
Also, the application will enable radio buttons after the "Measurements Finished" button has been clicked, asking if the measurements were valid. I need to detect this also.
Summary:
How do I detect when a button
(control) is enabled in another
application?
How do I get the handle of the other
application?
I am using C# with MS Visual Express 2010 on Windows NT, Vista & 7. If you suggest tools, I need them to be free as the company has a very tight budget.

I think you could do the job using FindWindow API, passing title and receiving the handle.
Then, enumerating children components, you could find the button (if you catch its name, next time you can use it to be quicker) and get the enabled state.
I think you could use AutoIT software (script) or its logic.
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr FindWindow(string strClassName, int nptWindowName);
EDITED:
Check this link to find a simple way to do what you need.
I hope this helps you.

Related

How to control power button press shutdown?

I'm working on a kiosk style application where I need to control the shutdown/restart of the PC when the power button is pressed. Thanks to this post, I'm about 90% of the way there.
In control panel set the acpi power button press action to shutdown.
Listen for the WndProc message WM_QUERYENDSESSION
When received issue the completely undocumented:
[DllImport("user32.dll", SetLastError = true)]
static extern int CancelShutdown();
Return from the WndProc and bring up my own message box asking the user to Shutdown / Restart or Cancel, and respond to their action.
Everything works well if I do a start / shutdown from the task bar (I can issue theses as fast as I want). Everything also works well the first time I press the power button. On subsequent power button presses though I see a minute or so delay before I receive the WM_QUERYENDSESSION message.
Is there a setting or registry entry about how often windows will issue an ACPI event? I know it's not the hardware because under linux the same machine will fire the ACPI event as fast as I can press the button.
Thanks.
Calling in some favors at work, I was able to take this question directly to Microsoft support. On my third support engineer, I was essentially told this is not possible at an application level. It was his belief that calling the undocumented CancelShutdown() "confuses" the power manager or acpi driver which leads to the WM_QUERYENDSESSION message delay. Since the CancelShutdown() is undocumented, MS is not willing investigate further.
So, how do you hook power button presses? You need to write a device driver, specifically an ACPI Filter Driver. We are investigating this now.
I don't think it is possible unless you speak with your hardware manufacturer or hardwire the start-button so that it doesn't send a signal to the hardware which handles this.
You can only delay it but even that would not give you 100% guarantee I guess.
Windows 8.1 will (maybe) bring a Kiosk Mode. Maybe that is what you are looking for ;-)

Handling minimized programs

I need help handling minimized programs when using a custom/self made explorer.exe file .. because unless properly handled, minimized programs will just shrink to something like 100x50px and stay on screen. I worked out a Timer in C# to check for "iconic" processes, list their mainWindowHandler, and move them outside the screen with "MoveWindow". To bring them back I use the handler and the "ShowWindow" function wich works AWESOME .. but as I said, it involves a constantly running Timer, so there must be a cleaner/easier way of achieving this.
Any ideas? Some way to hook and raise an event when a window is minimized?
*please note: show and movewindow are functions from user32.dll. I'm not trying to catch when MY forms are minimized, but when the OTHERS programs are.
You can create a hook to check when windows are being minimized.
I found a CodeProject article that uses hooks to check when the user opens a system menu (ALT+SPACE) on any window, and then appends an extra item to it. You can use that code to check when the user hits the minimize button, and run whatever code you need there.
The CodeProject article is written in C++, but you can adapt the same method for C# (or use P/Invoke).

Sending Commands to a Windowless Command Line process (started from the C# Application)

I've got a command line application that starts up and does some work. During that time, it listens to keystrokes (s => show status). It's not the typical command prompt where you press 's' and <ENTER> - it's the type which reacts as soon as the key is pressed the status is shown.
Now I'm trying to "control" that command line application from a fancy GUI application by sending keystrokes. I've tried the more conventional approach of writing to the Process' StandardInput but that doesn't seem to have an effect at all. Also, because the actual process doesn't have a window (it's started with CreateNoWindow=true) I can't try the Win32 API for sending keystrokes to a window.
Is there any other way of doing it?
Fancy console applications are problematic.
They have a tendency to directly read the keyboard input, instead of going through stdin. They also have a tendency to directly control their console, instead of going through stdout.
AFAIK, there is no way to programmatically control these apps. If you really, really need to, I would explore something like AutoHotKey controlling the app on a private desktop (AHK uses a virtual keyboard/mouse driver). I'm not sure how you would read the results off the console, though; it may be possible to create an intermediate console app that's started by your program (in the private desktop) and starts the target app. The intermediate app would then share its console with the target app and use low-level I/O to detect changes.
Or you could use Detours to bend the target app to your will.
Well, I seem to have found an answer to my own question.
It's a real "kludged together" solution, but it works - and for all the intents and purposes of the application I'm building, it doesn't matter.
So, what I did was use two WinAPI functions called
static extern bool ShowWindow(IntPtr WindowHandle, int nCmdShow);
static extern bool SetForegroundWindow(IntPtr WindowHandle);
The first one can be used to Show/Hide a window by changing nCmdShow to 1 and 0 respectively. The other one puts the window (determined by WindowHandle) to the front. Combining these two together, I was able to programmaticly bring the console window up front, do a simple SendKeys.Send(); operation and then hide it again.
// Use a WIN API command to bring the command line to front
SetForegroundWindow(workerProcess.MainWindowHandle);
// Send a keystore to re-display the STATUS of the worker
SendKeys.Send("s");
// Hide the window again.
ShowWindow(workerProcess.MainWindowHandle, 0);
Now, it's a real kludge job, but it gets the job done. One potential pitfall would be if a user is using the computer for something else, and would nail that 1 in a 10000000 moment when the window is active with a 'q' - it would quit the worker program. But the application is intended to be used on dedicated machines that most likely won't even have monitors, keyboards or mice attached to them so it wouldn't be an issue.
Thanks to all who answered, since you did - in one way or another, steer me towards the right solution.
I found an even better way to accomplish the functionality without the theoretical risk of causing problems with simultaneous user input and window-switching.
The trick is to use the WinAPI functions called PostMessage to send up KeyDown (or KeyUp) message to the process which does the same thing. No need to bring the process window to the front and hide it immediately afterwards!
I'm sending the key-down command with key 'S' as the argument:
// 0x0100 - VM_KEYDOWN
// 0x0101 - VM_KEYUP
// 0x53 - S-key
PostMessage(workerProcess.MainWindowHandle, 0x0100, 0x53, 0);
PostMessage(workerProcess.MainWindowHandle, 0x0101, 0x53, 0);

how to programmatically click on a button in running app using C# code

I want to write a C# program which will launch an .exe (this is an easy job, I know how to do it.) but now I want to add some more functionality to it.
I want to take user inputs to my program and want to pass them to running .exe as a input.Also I want to click on a particular button available on the exe window. Important thing is, I want to do it programatically without user knowledge that we are actually running that exe in background.
Please let me know if it is possible. It is very urgent.
Yes it is possible with Windows API. You need to send a message to that Window. At first use Spy++ to get IDs of all buttons you want to click. Spy++ is a Visual Studio tool and it shows you what messages are being sent to the application when you press those buttons. Then use PostMessage() function (Windows API) to send the same message programatically.
You can also for example look at Winamp (a music player for windows), there is documentation on how to press its buttons from external app. You can do it the same way for other apps, you just need to know IDs of all controls and names of windows or their classes.
here is code to click on Winamp's pause button:
#define AMP_PAUSE 40046
HWND hwnd = FindWindow("Winamp v1.x", 0);
if(hwnd) SendMessage(hwnd, WM_COMMAND, AMP_PAUSE, 0);
This is written in C++. If you do it in C#, use PInvoke to get access to Windows API. I assume you know how to do this. In the first step FindWindow gets a handle to the window, it identifies it by the name of its class. Then we use SendMessage or PostMessage to send the message. There are four parameters: window to send the message to, message id, and two parameters.
In Spy++ you can find those parameters you need for FindWindow and SendMessage. Please start it and play with it a little bit to see what it can do.
If you want to avoid directly use of WIN API, there's a small library that can help you with this, WindowScrape.
You can use it directly from C#.
Some of the features:
Search for windows and child controls registered in memory.
Change the titles of windows
Change the text of UI elements (permissions/privacy permitting)
Click on UI elements
Read the Titles of windows
Read the text from UI elements
Navigate through object hierarchies
Set object locations
Set object sizes
There might be other similar libraries, but at this point this is the only one that i'm aware.
Edited
Sample Usage:
using System.Windows.Forms;
//WindowScrape
using WindowScrape.Types;
namespace WindowsFormsTestApplication
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var npad = HwndObject.GetWindowByTitle("Untitled - Notepad");
}
}
}
If it is a WPF application you could have a look at AutomationPeers

Find which MDI child just got focus Win32 API

I have a program that has a MDI host and I would like to be able to get which of it children just got focus, bassiclly I would like to make a window focus changed event for this application.
The application is a 3rd party and I don't have the source, I have the window handle to the main program and the MDI host part.
I know I'll have to use Win32 API just not sure which ones.
I am writing my application in C#
Thanks.
I guess what you're looking for is intercepting WM_SETFOCUS and WM_KILLFOCUS messages
The real problem is how are you going to do this. I guess the easiet way is to install a hook which is a subroutine to monitor the message traffic in the system and process certain types of messages before they reach the target window procedure. You're doing it by using SetWindowsHookEx winapi function with WH_CALLWNDPROC or WH_CALLWNDPROCRET types of hooks. There some are examples posted on codeproject; also there is one on msdn: How to set a Windows hook in Visual C# .NET
What is not really clear in your post is where your code running: in the same process with the MDI windows or is it a separate application\service? In case it is you would also need to inject your code into the remote process. Check this link for details on how you can do it: Three Ways to Inject Your Code into Another Process
hope this helps, regards

Categories

Resources