C#.Net Check if 'Process' has a gui - c#

Is there any way to check if a variable of type Process currently has an opened GUI/window.
I'm using this to try and get all open application (with an open GUI) and then render their icons

I will try to answer this.
After a bit a research, I came across the following article in UserInteractive Property
So maybe you can try something like this:
Environment.UserInteractive
The above property is a boolean, which returns true if the current process is running in user interactive mode
And also you can look on this article: MainWindowHandle Property
which gets the window handle of the main window of the associated process, especially IntPtr which is the system-generated window handle of the main window of the associated process.

Related

How does Windows force "minimized" state from a desktop shortcut?

I have an application that is designed to minimize to the system tray. No issues there.
The problem I am having is that I cannot determine what Windows is doing to force the minimized state when I set up a desktop shortcut to that executable and launch it, such as:
I put some debug outputs in the form's constructor and launched via the shortcut. I get no command line arguments and a check of WindowState yields Normal. Yet the app starts minimized to the taskbar.
However, that's the rub: I want it to start minimized to the system tray, just as it would if the form were on-screen and the user minimized it. Not all the time, just when a "minimize" shortcut is used, or when the user clicks Minimize on the form, of course.
EDIT: for the curious...my initial testing was flawed because I checked in the constructor. Placing the test in the Load method produced a Minimized state, to which I could then react and call my code to perform the "minimize-to-tray".
Windows is starting the process with parameters to minimize the main window.
In C#, you can do the same by setting WindowStyle (MSDN) at ProcessStartInfo for use in Process.Start().
In the native world, you would use the CreateProcess (MSDN) API and pass a STARTUPINFO, setting wShowWindow to SW_MINIMIZE.
To query the window state, use GetWindowInfo (MSDN), look at dwStyle and check if WS_MINIMIZEis set. In C#, this should be in Form.WindowState.

Changing size and position of a window belonging to another process

I have a compiled c# console application and I would like to have an option to change a certain window (*.exe from, lets say, task manager) position and size.
Is it possible via the namespaces provided in VS2010?
The target window isn't connected in any way to the exe compiled by VS.
As said in the comments, you definitely have to use the SetWindowPos function.
You will need the window handle. For this you could call EnumWindows, checking the executable file name for each window using GetWindowModuleFileName.
Pseudo code:
foreach window in EnumWindows()
if GetWindowModuleFileName(window) == "program.exe"
SetWindowPos(window, ...)
These functions belong to the Windows API. To call them you will need to P/invoke (pinvoke.net might be of great help).
It's quite possible:
To change window position or/and size you may use SetWindowPos
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633545(v=vs.85).aspx
In order find out window's handle (hWnd argument) you may found useful
FindWindow
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633499(v=vs.85).aspx
EnumWindows
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633497(v=vs.85).aspx

How to open an application on active display while using Process.Start()?

I am using
System.Diagnostics.Process.Start(ProcessInfo);
to open a TEXT file in notepad from within my windows form application.
Detailed code snippet is
ProcessStartInfo PSI = new ProcessStartInfo("notepad.exe", LogFile);
PSI.WindowStyle = ProcessWindowStyle.Normal;
System.Diagnostics.Process p = System.Diagnostics.Process.Start(PSI);
However, it opens notepad on the default desktop but not on the extended desktop on which the main application is running.
Now, the question is, how to open notepad on the active desktop i.e. Window on which the current application is running?
Other that specifying the initial window state (normal, hidden, etc), you have basically no control over how the newly launched application starts up and where it shows itself.
The best bet here is to launch the application, then use its window handle to tell it to move. This all requires using P/Invoke, to call MoveWindow. The C# signatures for all of those functions are on pinvoke.net.
Here's a very simple (VB.NET) example that shows the basic idea. In this case, as #Lloyd points out, the window handle you need is the Process.MainWindowHandle you get back from Process.Start. Note that Process.MainWindowHandle isn't filled in immediately; you typically need to call WaitForInputIdle to make sure the window actually gets created. If MainWindowHandle is 0 then you'll know it's too soon.

How to get the window handle of another app minimized to the system tray?

Instance A is trying to restore instance B's window, but I can't get the B's window handle. I think the problem is that the window is being minimized by B to the system tray using:
this.Visibility = Visibility.Hidden;
And A is trying to get B's window handle using:
Process process = Process.GetCurrentProcess();
Process.GetProcessesByName(process.ProcessName).First().MainWindowHandle;
Which is equal to IntPtr.Zero.
I also tried to get the window handle by class name using Spy++ but the class name has a per-instance GUID in the following format:
HwndWrapper[FileName.exe;;ad445199-cf93-48a4-bd24-2f97d54c8af8]
That is because what you want basically doesn't exists, and the concept of MainWindowHandle is a gross misnomer that sneaked into the .Net Framework for everlasting confusion. From There can be more than one (or zero): Converting a process to a window:
"I have a thread ID. How do I get the
corresponding window?"
You can use the EnumThreadWindows
function to get all the windows on the
thread.
"Yes, I know about EnumThreadWindows,
but how do I get the window that I
want?"
Well, you haven't said what you wanted
yet.
"I want the window that corresponds to
the thread."
But which one? How will you decide
among all the windows?
"That's what I'm asking you!"
But you haven't yet described what you
want.
"I want the window corresponding to
the thread. Why won't you answer my
question?"
Note that saying, "I am looking for
the top-level unowned window" is a
step forward, but it still doesn't
uniquely identify a window. There can
be multiple top-level unowned windows
in a process. For example, Explorer
typically has lots of top-level
unowned windows. There's the desktop,
the taskbar, your open folder windows,
and property sheets. If you ask for
"the" top-level unowned window of
Explorer, which one do you want?
Perhaps people are getting the idea
that there is a way to uniquely
specify "the" window for a process
because the System.Diagnostics.Process
object has a property called
MainWindowHandle. The documentation
for that property doesn't do anything
to dispel the notion, either. I have
no idea how that property decides
among multiple top-level unowned
windows.
The topic is also elaborated in MSDN Q&A Get the Main Window:
Q How can I find the main window for a process? I'm writing a Spy-like tool and I need to get the main window (HWND) for a process so I can send it a message like WM_ACTIVATEAPP.
A Which main window do you mean?

Issue with EnumWindows

When enumerating windows using EnumWindows, I get hundreds of handles instead of one per open window on my desktop.
First of all, i am curious if this is the correct behavior.
Secondly, trying to get a difference between open windows before and after launching a process returns 15-20 new handles. I am wondering if there is a way to filter these based on some flag, i really need just the mainwindow handle.
Any ideas?
To get the main window of a process, use the Process.MainWindowHandle property.
To answer your question, you can see exactly what all of the handles are using Spy++.
In short, many applications will create hidden windows to run message loops.
You can filter within the enum callback by checking IsWindowVisible() & ignoring invisible system/message sink windows.

Categories