Console Applications in C# produce strange effect on other applications - c#

Hello and thanks always for your help.
I am having a strange problem here and I would like to hear your advice, comment or ideas about this. My trouble is that I can not reproduce the problem in my development computer
The situation
I have built a console application (in C#). It works great. Now other people are using it.
In the computer of one of the users, there is another application. By the sight of it, it is a windows application. I don't know the code of it, and I have been told in rather vague terms that "it was built in C#".
That application is basically some initialization in a window, close that window and then a login window appear with a button, two text boxes one which is for a password.
The problem that has been reported to me (and attributed to my console application) is that when the console application is running and not minimized, and then the other application is started the login window that appears does not have the first textbox in focus. Meaning that if I start writing nothing happens and I have to explicitly select that textbox to write in it.
When my console application is minimized or not running, the other application starts with the first textbox in focus (I can simply start writing- no need to select the textbox)
Now, my console application is rather complicated so I built a very simple console application
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleFocus
{
class Program
{
private static volatile bool keepRunning = true;
static void Main(string[] args)
{
//We manage to set the way to finish this program with CTRL+C
Console.CancelKeyPress += delegate (object sender, ConsoleCancelEventArgs e)
{
e.Cancel = true; //execution continues after the delegate
//we leave the whole program entirely
keepRunning = false;
};
while(keepRunning)
{
Console.WriteLine("I am still here");
Thread.Sleep(2000);
}
Console.WriteLine("Hit enter to finish...");
Console.Read();
}
}
}
and also a very simple windows application.
I tried the effect of both in the other application.
As expected even the simplest of the console application causes the loss of focus on the other application. Meanwhile the windows application does not cause anything.
So it seems that somehow console applications that catch ctrl-c to finish interfere with this application. (I have built my own applications and this does not happen at all)
Any idea why this could be happening??
Thanks in advance

Related

How to automatically close uwp applications

I have two questions, first: how to let the uwp application perform a function, automatically close the uwp through the code instead of letting the user click the close button on the top right; second: how to minimize the uwp application to the taskbar at startup, not directly on the desktop, thank you.
You can use the static exit method:
public void CloseApp()
{
CoreApplication.Exit();
}
or Use the non-static method ():
public void CloseApp()
{
Application.Current.Exit();
}
One thing you have to keep in mind is that using CoreApplication.Exit and Application.Current.Exit closes the app, but it does so without going through the normal app suspension - for the system it appears as a "unexpected termination". I also think the certification guidelines are against this approach.
As for taskbar minimization - this is currently not supported. If you need this functionality, you will need to build a WPF app packaged as UWP app using the Desktop Bridge.

Console Application: Closing Window vs End of Program

I'm writing a small library to help manage some objects in Excel. I'm testing this DLL using a simple console application that makes calls to the library, then prints the results out. I can then end the program in any of the typical fashions, usually by either hitting return (thus completing the ReadLine call) or hitting the window's close button. However, the reference to the Excel instance behaves differently based on how the program exits.
In my program, if no existing reference to Excel can be found, I use the following line:
_app = new ExcelInterop.Application();
where _app is an instance of Microsoft.Office.Interop.Excel.Application in either a static or singleton class (I've tried both, both have the same results).
Assuming the program creates it's own instance (and doesn't find one already open):
The instance will remain open if the program is exited by clicking the close window button:
The instance is released, and no longer appears in the task manager if the program is exited by reaching the end of the code in the Main block
Is there anyway to make all program ends behave like the latter case? Furthermore, this DLL will go on to be used in a WPF application, are there similar concerns in WPF? Or at large, even?
Perhaps most importantly, what are the technical reasons for this behavior?
A console mode program is a pretty hostile place for the COM interop wrapper objects that are needed for an apartment-threaded out-of-process COM server. This program demonstrates the issue:
using System;
class Program {
static void Main(string[] args) {
var prg = new Program();
Console.ReadLine();
}
~Program() {
Console.WriteLine("Clean-up completed");
System.Threading.Thread.Sleep(1500);
}
}
Try it both ways, by pressing Enter and by clicking the Close button. You'll see that the finalizer never gets executed. The operating system terminates the process before it gets a chance to shut down properly when you click the Close button.
Same problem with the finalizers for the COM wrappers. They cannot execute so IUnknown::Release() doesn't get called and the Office program is completely unaware that the client program is no longer there. Windows has its own cleanup for abandoned out-of-process servers but that doesn't work for Office programs for some otherwise mysterious reason.
That explains it, fixing it isn't so easy. You'll have to register a callback that runs when the Close button is clicked. If necessary, set the app reference to null if it is still in scope and force the finalizer to run with GC.Collect() + GC.WaitForPendingFinalizers(). Do keep in mind that this is just a band-aid, not a fix. It won't work when the user aborts your program while you are busy talking to the Office program. Avoiding a console mode project is best.

AppWinStyle does not work with Process.start

I am trying to use AppWinStyle with Process.start but it does not work as i expected.
The below code will open file 1.txt and it will be minimized with no focus to it.
Shell("notepad D:\1.txt", AppWinStyle.MinimizedNoFocus)
But below code will open 1.txt with focus on it.It will not be minimized.
Process.Start("D:\1.txt", AppWinStyle.MinimizedNoFocus)
Why does it happen? Please help me to solve this
A boilerplate example:
using System;
using System.Diagnostics;
class Program {
static void Main(string[] args) {
var psi = new ProcessStartInfo("notepad.exe");
//psi.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(psi);
}
}
Run it once to make sure it works, then remove the comment and observe the outcome. You'll briefly see the Notepad window flash but it immediately terminates again. Might depend on the Windows version, I described what happened for Windows 8.1
A GUI app gets the ProcessWindowStyle you specify through its WinMain() entry point, the nCmdShow argument passes the value you specified. What the app actually does with that value is entirely up to the app. Boilerplate implementation is to pass it to the ShowWindow() call, the one that makes its main window visible.
Using ProcessWindowStyle.Hidden is in general very problematic and a properly written GUI app will ignore it, like Notepad did. Because what you asked it to do is to start the program but not display any window, not even a taskbar button. In other words, you asked it to turn into a zombie, a process that runs without any way for the user to get to it. The only possible thing the user could do is run Task Manager and kill the process.
So sure, definitely expect this to not work. It shouldn't.
No such overload with Process.Start:
Process.Start("D:\1.txt", AppWinStyle.MinimizedNoFocus)
See all overloads here: Process.Start Method
In order to achieve it using the Process.Start, use the ProcessStartInfo.WindowStyle, setting it to ProcessWindowStyle.Minimized.
By the way, the AppWinStyle enumerator is specific for the Shell function:
Indicates the window style to use for the invoked program when calling
the Shell function.

Predicting that the program will crash

I've been using Google Chrome for a while now and I noticed that it features very elegant crash control.
Just before crashing, google chrome gave a message saying "Woah! Google Chrome has crashed. Restart now?". And right after, I'd get a standard Windows XP "This program has encountered a problem and needs to close." with the "Debug", "Don't send" and "Send Error Report" buttons.
My question is how can you program your compiled application to detect a crash condition in advance? If you have knowledge of how to do it in any programming language / platform would be great.
Thanks
Google Chrome uses a technique (often called process separation) where the 'host' UI manages child processes that it can detect becoming unresponsive (or worse, throwing an error and closing). It starts a new process for each tab you open.
Here's an article describing this in a bit more detail.
Using .net's Process class, you can start processes, check if they're responsive and even kill them.
If you want to embed a process' window within your own, you can use platform functions such as SetParent to move one window within another. I'm afraid I'm not aware of a managed alternative to SetParent when working with Forms, but I suspect one exists so it's worth searching for that before using SetParent.
If the host process crashes, simply using something like AppDomain.CurrentDomain.UnhandledException will allow you to receive a notification that a top-level exception has occurred, but by this stage you're unlikely to be able to predict the state of objects within your app and restarting (along with some logging and a notification to the user) is probably your only sensible option.
Handling top-level exceptions is covered in detail here.
I don't know Google's code so I am speculating. Google Chrome probably isn't predicting that it will crash, but detecting that it has crashed.
In Windows you can do this by providing a handler for all unhandled exceptions. In this handler you might do things such as restart the application, create a minidump file, etc.
Take a look at SetUnhandledExceptionFilter Function for one method.
In .NET, you can hook up to the System.AppDomain.CurrentDomain.UnhandledException event. Your code would look something like this:
using System;
using System.Windows.Forms;
public class Program
{
public static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += MyUnhandledExceptionHandler;
// start rest of application
}
private static void MyUnhandledExceptionHandler(object sender, EventArgs args)
{
MessageBox.Show("Your app is crashing. Watch out!");
}
}
There is a restart API. Daniel Moth has blogged about it here and here. Please note I am not saying this is the way Google Chrome works, just that it is something you might want to look into.
I believe you could also load bits of the app in seperate App Domains. I believe this is what the .NET 3.5 Addin framework uses, though I can't say I've ever used it (merely read about it). Looks like Daniel has blogged about this too.

How to create a Process that outlives its parent

I'm trying to launch an external updater application for a platform that I've developed. The reason I'd like to launch this updater is because my configuration utility which handles updates and license configuration for the platform has shared dependencies with other assemblies in the folder where the update will be deployed. So, while I can rename the configuration utility and overwrite it when deploying the update, I can't rename or overwrite the DLLs it depends on. Hence, the external updater application.
I'm handling all of the update gathering logic in the configuration utility, then attempting to launch the updater to handle the actual file copy/overwrite operations. Obviously, because of the file in use issues, I need the configuration utility to exit right after the updater begins.
The problem I'm having is that I'm using the standard Process.Start method of launching the updater, and as soon as the configuration utility exits, the updater process gets killed too.
Is there any way that I can create a Process that outlives its parent, or launch an external application that can run beyond the program that launched it?
EDIT:
Apparently, in my updater application, I miscalculated the number of command line arguments which are passed to it. Because of this, the updater would exit immediately. I misinterpreted this to mean that the launcher application was killing the "child" process, when in fact, it wasn't.
The answers below are correct.
It seems that the problem you are seeing has a different reason because the Process class will not kill any processes started using Process.Start when your application exits.
See this simple sample program, the calculator will stay open:
using System.Diagnostics;
class Program
{
static void Main(string[] args)
{
Process.Start(#"C:\windows\system32\calc.exe");
}
}
There's no reason why a process started with Process.Start should automatically die when the launcher exits. My guess is that you're doing something odd in the updater.
I've written an updater doing exactly this kind of thing before, and it's been fine.
For example:
Launcher.cs:
using System;
using System.Diagnostics;
class Launcher
{
static void Main()
{
Console.WriteLine("Launching launchee");
Process.Start("Launchee.exe");
Console.WriteLine("Launched. Exiting");
}
}
Launchee.cs:
using System;
using System.Threading;
class Launchee
{
static void Main()
{
Console.WriteLine(" I've been launched!");
Thread.Sleep(5000);
Console.WriteLine(" Exiting...");
}
}
Compile both of them, separately, and run Launcher.exe. The "launchee" process definitely lasts longer than the launcher.
Just a thought from my foggy memory, but I seem to remember having a discussion a while back that when the Process.Start method is called from Form that the spawned process has some sort of dependency (not sure what, why or how, memory is a bit foggy).
To deal with it, a flag was set that was actually called from the Main() method of the application after the main form/app exited and that if the process was launched from the Main() method, eveything worked out just fine.
Just a thought, like I said, this is purely from memory, but some of the examples posted here all being called from the Main() method of a console app seemed to jog something.
Hope all works out well for you.

Categories

Resources