I have a C# VS2017 Console App. I'd like the CMD prompt to return immediately after executing while the App runs in the background (it's a long running process).
Currently I'm starting the App as a Process from another executable just to do this by setting Process.StartInfo properties.
Is there an opposite to Process.WaitForExit() that can be set at the start of a program?
I read somewhere using a WinForms App without the form might work, yet I tried to delete the form and sleep for 10 seconds, showing a MessageBox after (in Main). The program returned and showed the box immediately without sleeping.
Related
I am hoping to check at the beginning of an automated test if an application is open. I can check if the process is running by doing the following
foreach (Process proc in Process.GetProcesses())
{
if (proc.ProcessName.Contains(name))
{
return true;
}
}
However, the process I want to find starts up about a minute before the application actually opens and is ready to be used by the test methods (its a very slow starting application). The above code sample looks at all windows processes running, but I am wondering, is there a way to do a similar method but to look at windows applications running?
There is a method already in class Process that you can use to check if an app with a UI has fully started:
Process.WaitForInputIdle(int milliseconds)
This will wait up to milliseconds ms for the message loop to become idle (and returns a bool to indicate success status). Depending on the application you're waiting for, you might want to allow 30 seconds or longer.
This might work for you, but be aware that in my experience for some applications it is not totally reliable!
The Windows API documentation has more details about the Windows API function that WaitForInputIdle() calls behind the scenes.
When a process is started, you can say application has started.
What you want is to wait until application startup progress has completed or not.
This means, when process is started, application startup begins. When application startup is completed, is becomes ready for user input. So I think you should have a look at following question and its answers.
Programmatically, how does this application detect that a program is ready for input
Apllication is proces.
If you can modify app, at app start you can create file and at end delete it. So you can chceck file existance. If file exist app starting/started.
If you need info when main form is created use:
WINFORMS
Form.Shown event.
WPF Loaded Event
uITestControl.Exists did the trick for me.
This method will return a boolean value corresponding to the existence of the application window being open. This allows an if statement to be created that can open the application if not already open, or do nothing if its already open.
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
I need to create running windows process (the one seen on task manager) when a Windows form loads because I need this application to be monitored by nagios (http://www.nagios.org/).
So when the form loads, an exe will run in the background process, and when form closes, the process will have to stop too.
Update
So when the form loads, the current ApplicationName.exe will display in the Task Manager Processes Tab, and when form closes, the ApplicationName.exe will have to stop too.
I also found out that when you Start Without Debugging, the ApplicationName.exe will display in the Processes Tab of the Task Manager but if you Start Debugging (F5), you wont see the ApplicationName.exe in the Processess Tab. Now i want to make sure that even if I will Start Debugging it, I can still see the ApplicationName.exe in the Processes Tab. How do i do that?
Clarification needed: is the additional process that is running the Nagios monitor, or something else you create?
Either way, you can use Process.Start() to kick off a separate application from within your own:
//event handler for the form's Load event
public void MyWindow_FormLoad(object sender, EventArgs e)
{
//kick off the process you want
Process.Start(#"C:\Program Files\MyOtherApp\MyOtherApp.exe");
}
There are overloads allowing you to specify arguments, or customize the startup behavior of the process. But this is the basic call and (given a real program location) should kick off the separate EXE as a new process with default startup behavior (as if you'd double-clicked it in Windows Explorer).
Now, if you need more, like a way to have the two programs talk to each other, then you'll need to expand your question with the appropriate details.
EDIT FROM COMMENT: Ah. OK, that's slightly different.
Normally, any EXE that is running at any given time will appear in the Task Manager's processes list by default, with no special coding necessary. It's in fact very hard to get a proces to NOT show up in that list, because a process that doesn't want to be seen is one of the hallmarks of a virus.
However, when you run an app in Debug mode from Visual Studio, the code is compiled and run from within VS's process boundaries, and doesn't show as its own process. To get it to show up as its own process in Task Manager, the compiled application must be run from outside VS. You can still debug it, by "attaching" VS's debugger to the running process after you have started it. But, this means that the app must be stable and long-running enough for you to manually attach to it. A program that has finished most or all of its execution by the time it reaches a "resting" state will need some modification in order to wait for you to attach to it before doing whatever it was you wanted to debug.
I have Test.exe ,a sample winform app. and used it as Process
public Process process = new Process();
protected override void OnLoad(EventArgs e)
{
process.StartInfo.Verb = "open";
process.StartInfo.FileName = "Test.exe"; //Give your App or Process Name
process.StartInfo.WorkingDirectory = #"C:\Users\sali\Documents\Visual Studio2010\Projects\Test\Test\bin\Debug"; //Give your App or Process path
process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
process.Start();
}
I hope it helps
Or if you require something different, feel free to ask
If you just want a Windows form application you have written to show up in the list of processes when it runs then you will find it does anyway. You do not need to do anything special for it to run in its own process. For example I made a simple out-of-the-box Windows form application in VS2010
And then ran it (without debugging) and here it is in the process list of Task Manager.
(N.B. I'm running Win8, so your Task Manager may look a little different.)
If however you need to know when a Windows form application not written by you is started and stopped by the user you'll need to look at Windows hooks as mentioned in the answers to this question or at the process creation/modify/shutdown events in the Windows Management Instrumentation(WMI) API.
I have a winforms application that sometimes used from the command line.
Here is the code (simplified of course):
[STAThread]
static void Main()
{
AttachConsole(ATTACH_PARENT_PROCESS);
Console.WriteLine("Hello");
/*Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());*/
}
If that was a console application the output could be:
C:\ConsoleApplication\ConsoleApplication.exe
Hello
C:\ConsoleApplication\_
In case of windows application its actually:
C:\WindowsApplication\WindowsApplication.exe
C:\WindowsApplication\Hello
_
Can anyone tell me why do we have such difference and is it possible to make my windows application to behave like console when running from cmd?
edit:
I want my windows application to behave like console when running from cmd:
C:\WindowsApplication\WindowsApplication.exe
Hello
C:\WindowsApplication\_
solution:
As a result I'm running my application as
C:\WindowsApplication\start /wait WindowsApplication.exe
Yes. The difference is that cmd.exe is aware of the kind of executable. It knows to wait for the process to terminate when it is a console mode app. It does not wait when it is a regular Windows gui app. Trusting that it will create its own window. So it displays the command prompt again, your output gets appended to that. You'll also have trouble using Console.ReadLine() btw.
You'd have to start your program with start /wait yourapp.exe to force cmd.exe to wait. Calling AllocConsole() instead is the only universal fix. Also takes care of creating the console when your app gets started from a shortcut.
AllocConsole() is fairly disorienting. Consider writing a tiny console mode app that does nothing but Process.Start + WaitForExit to start your main program. Perhaps also munging the command line arguments. Now you get the blocking behavior back. If you rename the executable to mainapp.com (to start mainapp.exe) then the difference is hidden quite well, a trick that VS uses as well (devenv.exe vs devenv.com).
There is a flag in the exe, telling if this is a console app or gui (winform in your case) app. When you start an app, Windows will detach the console from the program if it is a console app. You can use the following approach to achieve what you want:
Compile you application as gui, name it mytool.exe
Create a doskey alias mytool=start /wait c:\path\mytool.exe $*
In this way, when you start mytool.exe in explorer or shortcut, you start a normal windows application; when you type in mytool in console, you actually start it by "start /wait", which will not detach the console regard less of the flag. (However, you do need to attach to parent console in your app if you want to output/input something from the console.
You want the Windows App to block the Console thread as long as it's running, if I understand you correctly. I have no idea why you would do that, but I can give a shot at how it might work:
Change the WinForms application to a console application, that opens a form. This way it would block the console thread while displaying a window.
I have a C# windows application. I placed it on a test server, whose set up is not controlled by my company and neither is the seurity context. I double click the exe. App runs and i see my form. I close the application, i open task manager and i still see a foot print of the applicatiion.
taskkill does not seem to remove it and it is still running in task manager.
how do i check if any resource is still being held?
The likely cause is that a background thread is still running after your application is closed. Depending on your framework and application configuration a background thread can cause a process to keep running even after the main window is closed.
Do you have any threads in your process? If so make sure to close them out when the main application window is closing. A good place to do this is in the OnClosing method of a Windows Form
Abusing Application.DoEvents() is another way to get into this kind of trouble. If you cannot kill the .exe from TaskMgr, your app is stuck waiting for a driver to finish an I/O request.