Wait for process to show up - c#

I have an application that launches a process using Process.Start. The process will either show up the actual window after a few seconds (depending on how much time it took to load), or will show a MessageBox with an error message.
After I'm using Process.Start, I want my application to wait until either the window showed up or the MessageBox showed up. I tried using WaitForInputIdle and checking if Handle is 0, but they both don't work.
How can I wait until the process emits an actual window?

I think you should just catch window openings with Automation as recommended here:
Most Efficient Way for getting notified on window open

Related

Process.CloseMainWindow equivalent for a program running in tray?

I have installed a program ("CmisSync.exe") that runs as a small icon in the Windows system tray.
From C# I want to start it, and then exit it gracefully (as if a user had clicked "Exit" in the program's menu). Here is my attempt:
Process process = Process.Start(#"C:\Programs\CmisSync\CmisSync.exe");
// Wait for CmisSync's configuration/UI to start properly.
Thread.Sleep(5000);
// Close as if the user had clicked "Exit".
process.CloseMainWindow();
// Wait for CmisSync to finish what it is doing and exit normally.
// This might take a few minutes if a big sync is going on.
process.WaitForExit();
Unfortunately, CloseMainWindow does not make the program stop.
Maybe it is due to the program not actually have a main window? It only runs in the tray.
Close does not make the program stop either, by design.
Kill is not graceful, it does not let the program finish its current UI loop. Unlike the UNIX equivalent, the command does not seem to accept arguments indicating how brutal the kill should be.
The tray icon is implemented using System.Windows.Forms.Form
Yes, as you have discovered Process.CloseMainWindow only closes a program with a main window i.e you will most likely find the MainWindowHandle will be IntPtr.Zero
Process.CloseMainWindow Method ()
Closes a process that has a user interface by sending a close
message to its main window
Additionally, AFAIK WM_CLOSE or any other message wont help you either
However, you could create a message only window, or have your mainwindow set to invisible so you could message it in standard ways or call Process.CloseMainWindow.
However there are also many other IPC techniques you could use to the same affect, or even WCF. Anyway, since you're in control of the sync tray icon program, you can employ anything really (well except techniques that require a window evidently)
Interprocess Communications
Update
Since its open source, you can either edit as desired or have a look at the internals of it and you might find a way to gracefully close it.

WaitforInputIdle doesn't work properly

I am trying to launch a process from my WPF application.The process is also a WPF application developed using PRISM/MEF framework.
var process = Process.Start(processPath);
process.WaitForInputIdle();
Console.WriteLine(process.MainWindowHandle);
//rest of the code
The problem is with PRISM/MEF application as process WaitForInputIdle() doesn't work.I tried printing mainwindowHandle and its zero after WaitForInputIdle().
Whereas I tried opening other process like notepad.exe ,WaitForInputIdle() works and prints the window handle.
Now I am using this workaround ,but can anyone tell why WaitForInputIdle() is not working properly?
var process = Process.Start(processPath);
process.WaitForInputIdle();
Console.WriteLine(process.MainWindowHandle)
while (process.MainWindowHandle == IntPtr.Zero)
{
Thread.Sleep(10);
}
//rest of the code
The Process.WaitForInputIdle() method just waits for the process's message loop to enter an idle state. Like your loop WaitForInputIdle() is also a workaround, it is not specifically coded to wait for the MainWindowHandle to be created. So depending on how the application works there's no guarantee that the window handle has been created by the time the method returns.
At least most of Windows's built-in apps uses the same methods as the Windows Forms applications for starting the app and creating the first window. In those cases the standard behaviour is that the process will enter an idle state when the window handle is created and the window is shown.
WPF, Prism and MEF works a bit differently than WinForms, thus there's no guarantee that the window handle has been created when the application finally enters an idle state. Unfortunately I'm not very much into WPF nor Prism or MEF, so I cannot even provide a theory about this behaviour.

Prevent MessageBox from minimizing other windows

In my project I have a MessageBox that pops up from time to time.
When I'm playing a game and the MessageBox appears, the game is minimized and I'm back to the desktop.
This might depend from app to app, but this specific app/game minimizes when MessageBox appears.
How to avoid this behavior? Is there anything I can do to the MessageBox to make it lose focus/not activated ? I tried to look at the MessageBox methods but no luck.
It sounds like you want the message box to be able to display while the rest of your code is still running. Type of messagebox you are using is modal and needs to be closed until it allows you to interact with the other open window.
I suggest you start a new thread for the message box so that the thread can continue to run allowing you to be able to interact with the other windows.

Using the Scrollbar interrupts the Console Application

Currently when I use the scrollbar on my c# console app, it seems to halt/interrupt the application until I "let go" of the scrollbar.
Is there a way to keep this from happening?
Here's an old post I'm just quoting from, which explains the Pause when using the scrollbar in cmd prompt :
"Technically, only displaying output is suspended while you hold the scrollbar: the console subsystem temporarily stops reading from the output buffer and displaying it. However, the process remains running, and said output buffer fills up very quickly, which makes all further write()'s "block" for as long as the buffer is full. This is what makes the process appear to pause.
(Note that there are two distinct components – the console window and the programs running inside. The "Command Prompt" is only the cmd.exe command interpreter, but the window along with scrollbars is displayed by CSRSS."
Here's the link to the post : https://superuser.com/questions/344262/windows-command-prompt-pause-during-mousedown
You will need to run your long-running code in another thread, then writing to the console when need be - see this post: Using .NET BackgroundWorker class in console app

C# output on both form textbox and console application using RedirectStandardOutput and Error streams

The question here is if anyone has an idea how to both get StandardOutput data to print in Windows form application and keep the output in the console itself. The WinForms part I have completed already, it works great with process events and invoking form elements. At this point I am pretty sure that after re-directing output, Console.Writeline() doesn't print anything on the console window anymore. Any ideas besides running another dummy process that simply displays anything whats on InputStream?
Also
While I'm at this. Is there any way to access process that is on another thread? Since whenever I try to access it it shows that its out of scope.

Categories