I use the c# process class to open a separate application that has no GUI. it is s a c++ project that I use the Process.Kill() on to end it. The problem is this doesn't give it a chance to finish its actions. Process.Close() just releases the object in my main app and and leaves the separate application running.
Whats the best way to make this process close gracefully?
In the past I needed to start a non-gui C# tool from a GUI C# tool, both of which I had written. I used the standard input/output streams to communicate between both tools.
You could make your C++ tool listen on its stdin for a command that indicates the tool should quit gracefully. Then, in your C# application, send the quit command, wait for a reasonable amount of time and if the tool hasn't ended by then, kill it.
I'm sorry that my C++ is not good enough to give you an example for the C++ side, but the following lines are used in my C# project to tell the external process to end:
m_consoleProcess.StandardInput.WriteLine("QUIT");
m_consoleProcess.WaitForExit(10000);
if (!m_consoleProcess.HasExited)
{
m_consoleProcess.Kill();
}
If you need to manage separate external processes, of course you need to store one Process instance for each of them and you have to handle the case that the external process was ended before your application should quit.
Related
I have developed one application in C#.net 3.5 and VS 2008, which contain many controls such as tab, textbox, objelistview, gauges, zedgraph.
My application is intended to communicate on serial port and update the data on said ui. To achive this i am using another timer thread.
Its 24X7 running application, but sometime it just freeze and timer thread stops executing automatically, i can see the sceen but can't click anywhere and simply i need to restart application to make it run again.
Please note i dont see application not responding message or likewise, it just simply freeze.
If any one can provide any inputs for the same it would be great.
You may have memory leaks or too many uncolsed resources. While your application is freezed see Task Manager and check Memory and CPU usage. They can help you gueesing if too many of RAM is used or if your application consumes too many CPU processing power.
In your application consider disposable objects. Try to dispose them correctly. After opening a serial port don't forget to close it again. Also you can use logging mechanisms to see at what point your application freezes.
Try implementing a watchdog using System.Threading.Timer and check if thread responsible for communication is responsive. Also, I'm not sure what do you mean by "another timer thread", but again, you should use aforementioned class to track time between datapolls and use callback method.
Please also remember, like afsharm said, that you need to free resources you don't use anymore, so either get one handle on your COM port and use it or just release it everytime update has ended.
Windows Mobile 6.5
I have a process which uses System.Threading.Timer upload some data to net at specified intervals.
Now I want to terminate this process from a GUI application. I can use process enumerator to get Process object. What happens when I call Process.Kill? Does it jsut terminate it, the process could be in the middle of reading/deleting data from local database and sending it to service. What can I do make sure that atleast if its in middle it does not terminate and once it is done it can terminate before next Timer event fires?
Terminating an application like that cuts it off at the knees, introducing the distinct possibility of corrupting data. The only way around that is to not terminate the process.
You'll have to introduce a way to communicate to the application that it need to exit so that it can finish whatever it's doing so data won't be corrupted.
i.e. the application must be written in a way to accept a request like that (however you want to do it).
I am writing an application that has both CLI and GUI.
I read most questions and articles regarding it, and found highly usefull this question:
Can one executable be both a console and GUI application?
My final code looks like:
if (args.Length > 0)
{
//console code
}
else
{
FreeConsole();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form());
}
This works great when running the .exe by double click, or when debugging, or from console with arguments.
However, when running it from the console with no arguments, the GUI is opened, like I intended, but the console is stuck waiting for the GUI to close.
This is uncharacteristic GUI and console behavior. the console usually launch the GUI and not wait to its exit, but for new commands.
Is there is a way to avoid it?
The accepted answer in the question you linked to contains this passage:
Junfeng's second technique is what ildasm uses. He quotes the process
that ildasm's author went through when making it run in both modes.
Ultimately, here's what the it does:
The program is marked as a console-mode binary, so it always starts
out with a console. This allows input and output redirection to work
as normal. If the program has no console-mode command-line parameters,
it re-launches itself. It's not enough to simply call FreeConsole to
make the first instance cease to be a console program. That's because
the process that started the program, cmd.exe, "knows" that it started
a console-mode program and is waiting for the program to stop running.
Calling FreeConsole would make ildasm stop using the console, but it
wouldn't make the parent process start using the console.
To me it looks like the headache of having a binary trying to switch between the console subsystem and GUI subsystem (which really isn't allowed) is more effort than it's worth.
One approach would be to have a separate GUI application .exe. Whenever the console app is started without parameters it launches the GUI app and closes itself.
To prevent code duplication this probably requires all the actual logic of the application to be put in a separate class library.
THe usual way to do this is to abstract presentation from logic and then have two exes, one CLI, one GUI, not to have one that could be either. Going down that route leaves you with some sort of awful compromise with the benefits of neither approach.
GUI with command line options is not a CLI app, it's a GUI with an invisble / short lived window.
Maybe is not an answer to your direct question, but with this dual solution you are asking for trouble :) This is a hack that will work in some cases, but in other not.
Proper solution would be exclude functionality and application logic in separate class library and then from both console and GUI application call that "engine". Put all that three projects in one Visual Studio solution. All functionality and vast majority of code should be in that class library, GUI and console projects would only deal with that specific aspects that depends on environment (eg. button click event would only be in GUI app etc.)
This looks correct. You launch a command that only returns when the application is stopped.
If you don't want to wait for it to return, start it in a new thread. (ThreadPool, Thread, Task, async/await in C#5.0 => pick your favorite).
Need to start a gui application from console without stuck the console? From the command prompt type:
start "[title not necessary for gui exe]" "full path to .exe"
See here
Best approach to write application working in GUI/CLI/CUI/Network mode is using libgreattao.
Search for it on sourceforge.net.
Libgreattao decouples business logic and communication mechanism, so you can put libgreattao related code everywhere in your program.
I wrote a C# NET application (Console app that is run as a Service) that manages a Java process (Minecraft Game Server), and our Web Panel software manages my application. When the Java process stops, my application stops itself, and when my application stops, it stops the Java process.
The issue I am running into is that I deployed the software to all of our machines after extensive bug testing, but there seems to be a bug we missed where it is NOT shutting down the Java process sometimes. This bug is horrible as the Web Software tries to start my application, my application tries to start the Java process, but fails due to it being unable to IP bind (since the old process stayed open) and we wind up with 15-30 bugged Java processes running.
I am using CurrentDomain_UnhandledException to catch my application's crashes and call TerminateProcess().
I am using CtrlTypes.CTRL_C_EVENT and CtrlTypes.CTRL_CLOSE_EVENT to detect my application being closed which also calls the TerminateProcess() function.
I have tried both of the following methods...
static void TerminateProcess()
{
log.LogMessage("Minecraft Process Shutdown.");
SendProcessCmd("stop");
}
and
static void TerminateProcess()
{
log.LogMessage("Minecraft Process Shutdown.");
minecraftProcess.Kill();
}
However, I seem to be missing another way that my C# application is being shut down, because both ways seem to leave a Java process running every once in a while that I can't reproduce locally.
Well, you did not state any question, I’m going to guess you wanted to ask for other ways a process can get shut down, so that you can intercept it and ensure the Java process termination. Simply said: That is impossible (in full generality).
Just look at your own code: You are doing exactly the same thing to Minecraft: Calling TerminateProcess causes the target process to terminate immediately, without any chance to clean up. Should anyone call TerminateProcess on you (e.g. a user killing the process from Task Manager), your process just terminates immediately.
Also, some fatal exceptions are uncatchable, e.g. when your process dies on a stack overflow, you are not told, just terminated.
I guess you’d need to create another process, watching over your process… (Or rethink the whole architecture, creating and killing processes, especially with TerminateProcess, seems a bit rough to me.)
So i have a helper process written in C++ and I open it, feed it arguments, and it feeds my program back information through the standardoutput stream.
PS. I don't have the source for the helper process exe.
If my application were to be terminated from the task manager, or for some reason crash, how could I ensure that my helper exe is closed? Is this possible? Would I need an external file?
Use Job Objects to manage groups of processes. In this case you want to create a job object using CreateJobObject, use SetInformationJobObject to set the JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE flag, and assign the helper process to the job using AssignProcessToJobObject. Don't close the handle to the job object unless you want to kill the helper process. When your process terminates (through any means), the handle will be closed and your helper process will be killed.
You should create an inheritable duplicate of the parent process handle and pass its value to the helper process on the commandline. The helper process can then wait on that handle on a separate thread (or the main thread if you're clever). When the handle becomes signaled, it means that the launching process has terminated.
Edit
Since you can't change the helper process, your options are more limited. Your could try attaching a handler to the launching process's OnAppDomainUnloaded event, but I'm not sure this will work in all the cases you're concerned about. You could also create a third process to monitor the first. This process would work as I described above. If you wanted to get really fancy, you could inject a remote thread into the helper process to monitor the parent. This is very technical, so I recommend against it.
The easiest way would be to close it on normal application exit and when AppDomain.CurrentDomain.UnhandledException is invoked (i.e. your app is about to crash)