How do I manage an external Windows application in C#? - c#

What is the best way to manage an external windows application in C# (or .NET)?
So far my I've been able to launch a process using System.Diagnostics.Process, however this simply allows me to launch/kill a process. (from what I've gathered)
I noticed System.Diagnostics.Process has a CloseMainWindow() routine which will send a request to a process' window. Can I use this Process class to send different messages? (if so, can anyone point me in direction of where I can learn about these windows messages)
I need to be able to manage an external program and manipulate it the following ways:
1) Launch
2) Kill Process
3) Show Application (Fullscreen and in taskbar)
4) Hide Application (Fullscreen and in taskbar)
Further details:
Windows 7, Restricted to .Net 3.5 Framework

You might be able to use interop and use SendMessage to do all of your functionality. See this: http://pinvoke.net/default.aspx/user32.SendMessage

Try sending a message to that window. Take a look at SendMessage . The messages you need are SW_MINIMIZE,SW_RESTORE and SW_SHOWMAXIMIZED.

You're going to need to use some Win32 P/Invoke stuff to send window messages in order to do what you want.
See this code sample on ShowWindow or SendMessage which tells an external window to show or hide itself. You'll first need to get the window handle you want with FindWindowEx.

you can do all you want in different ways, once you start the process yourself or you find it in the list of running processes, using classes or methods of System.Diagnostics.Process, then you can follow different options...
for example consider that once you have this handle: Process.MainWindowHandle you can send messages to that handle, with SendMessage and PostMessage and this allows you to do very very much; or you can use PInvoke APIs like SetWindowPos or ShowWindow or SetWindowLong and do basically really everything...
see this for example:
How to use the ShowWindow API to hide and show a form
I can send you more links but won't like to refer to the whole MSDN ;-)

Related

Register to window messages using 'hwnd'

Assuming I have a valid hWnd to an active window (it was retrieved using ‘GetForegroundWindow’ or FindWindow, for example), can I register to windows message of this hWnd, from another application, of course? Is there any Win32 API for this, or a built-in C# method?
Example: In my console application I have a hWnd to the ‘Notepad’ window (running in the background). Can I register somehow to messages indicating the ‘Notepad’ window had moved, changed size, minimized, closed, etc.?
Thanks,
Elad
You have to inject a DLL into the process that owns the window. Use SetWindowsHookEx(), WH_CALLWNDPROC hook. You cannot write such a DLL using the C# language, the process won't have a CLR initialized and ready to run your code. Native code is required. Check this project.
If you just need to know about it moving or closing, then check out SetWinEventHook. You'll have to write a P/Invoke wrapper for this, since there's no equivalent in the .Net API. You can use this without needing to inject a DLL (use the WINEVENT_OUTOFCONTEXT
flag), so can keep everything in C# (and it also avoids the hassle of having to communicate between a separate DLL and your main process).
You'll likely want the events EVENT_OBJECT_LOCATIONCHANGE and EVENT_OBJECT_DESTROY. Note that you get these for all HWNDs on the thread you are listening to, so you'll need to filter by HWND in your callback.
Note that when you use WINEVENT_OUTOFCONTEXT, your own code will need to have a message loop running on the thread that calls SetWinEventHook. Also, the notifications that you receive are not delivered instantly, but with a slight delay (similar to PostMessage), but that may still be fast enough for your purposes that you can avoid doing an in-proc hook.
You can use the Accessible Event Watcher app (AccEvent) that's part of the Windows SDK to see what messages are available from notepad before you start writing code.

how to close a window from a different process

I have a c# application which I want to instruct to shutdown nicely, from a different process.
I also want to be able to ask it to open its main window.
I have a reference to its main window handle.
I know I can do it using elaborate schemes such as remoting or WCF.
the question is can I do it using simpler mechanisms such as window messages, or the OnClose event handlers of the window in the c# application
Pinvoke SendMessage() to send the WM_CLOSE message to the app's main window. Asking it to open its main window is probably going to be quite difficult, you cannot obtain the window handle until the window is created. Process.Start() would be the normal way.
A low cost alternative to WCF and superior to pinvoke is a named pipe or a socket to interface with the app. This requires being able to modify the source code of the app.
Process.CloseMainWindow
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.closemainwindow.aspx
I think that you could probably use FindWindow to find the correct child window and then SendMessage or PostMessage to send a WM_CLOSE.
Here's another StackOverflow question that deals with doing this in C#.
Edit: Though as the other answer says in that question, you might be able to use Process.CloseMainWindow instead.
I would first make my target application "aware" of the fact that some other process might like to trigger its closing or opening of a window or doing any action. This should be implemented similar to calling any method on another process through the target app's api or public methods. ..unless you are trying to do something with 3rd party applications, I think you shouldn't attempt to directly send them messages to close or shutdown.

How to get/set data of(into) visual components (of windows programs) programmatically?

I am talking about windows GUI programs. Say a program-window has a dialog box (or a confirm button) asking user input. How can I provide input to that program using my program (written in say C#, Java or Python). Or say, a program window is showing some image in one of its panels. How can I grab that from other(my) program. It is a kind of impersonating (or inter-win-program messaging?). Someone told me it can be done using spy++. But how? Can you explain? What code to write? What to do with spy++?
spy++ is listening for all win32 messages. It is very useful for debugging an application but I don't think that it is a good idea to use it as an inter-process communication mechanism.
You can use win32 apis to send input to your program. As an example, You can modify the content of an edit text by using the SetWindowText function.
You need to get the handle of the window. You can use the FindWindow and the GetDlgItem to get it.
It will work for c++ and python thanks to win32 python extension. I don't know if there it is possible to use win32 api from java.
To programmatically generate key presses, see Key Presses in Python, and search for "generate", "key", "emulate", "fake".
To programmatically capture the screen, see Capture screenshot of active window?, and search for terms like "capture", "window", "screen".
If you want to write win32 code to do it, start here:
http://msdn.microsoft.com/en-us/library/ms632589(VS.85).aspx
If you just want to hook the gui as easily as possible, investigate:
http://www.winbatch.com/
http://www.autoitscript.com/
http://www.autohotkey.com/

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

Monitor process start in the system

Is there a way to monitor processes starting in the system before they start?
Example:
On programs like ZoneAlarm or Antivirus programs, when you run a program it asks you if you allow running this program or not before it runs...
There's a few ways to do this. If you only need to track process creation coming from a specific program (or a few programs), the EasyHook/Detours method mentioned here will work pretty well, but you effectively need to install a hook on CreateProcess into each program, so it's not a great solution if you want to track all process creation in the system.
There's a specific API for this in NT-based Windows variants (NT/2000/XP/Vista) called PsSetCreateProcessNotifyRoutine(). Unfortunately, you can only call this function from ring0, so it needs to be done in a driver. There's a handy explanation (and code) in this CodeProject article: http://www.codeproject.com/KB/threads/procmon.aspx.
AFAIK, this is just a notification, and does not by itself allow you to tell the system whether the process should be created or not. However, if you needed to do this, you could pause the process (e.g. by attaching to it as a debugger) while your code decides whether to kill it or not.
You should check out the easyhook-continuing-detours project, which is a .NET port of the Microsoft Detours project. It will allow you to hook unmanaged APIs (such as CreateProcess). Check out code examples for a simple FileMon-like program here.
You can find out when processes start via using a real-time ETW consumer - however, to be able to take some action that could possibly cancel the process from starting, you'll have to do something shady / undocumented, like hooking CreateProcess, or using a kernel filter driver to block reads to the EXE.
Just use process creation notifications .
It's included in Windows.
You don't need to hook anything.

Categories

Resources