views:

118

answers:

5

I have a old command line based program (its fortran if that matters) that is opened from a C# application when a user clicks a button. If the command line program is shut down while it is running data becomes corrupted. Is there any way to prevent people shutting it down while it is running? Like make the [x] not be available or somehow embed the program into mine?

 System.Diagnostics.Process pname =
 System.Diagnostics.Process.Start(Path.Combine(Application.StartUpPath,
"diag_main.exe"));

    pname.Exited += new EventHandler(pname_Exited);

Note: I want to still be able to see the application running and it closes on its own when it is finished, I just can't have people killing it while it is in the process of running.

+1  A: 

Unfortunately, no. If the other program has a UI, then you can't hide it from the user. If it doesn't, then you can launch it without presenting a console window by using the ProcessStartInfo class. Even if you do that, though, they could still kill it using the task manager.

Adam Robinson
A: 

If the program is loading in a cmd window, then no, there's no way to prevent the user from just closing the window. A better approach would be to launch the program in the background, where it's hidden from casual users. A malicious user could still find the process and kill it, but that's likely to be less of a problem.

You can do this with the following:

var psi = new ProcessStartInfo();
psi.CreateNoWindow = true;
/// etc.
JSBangs
+1  A: 

I don't know if this will apply to your app, but you can start the process with a hidden window - this would mean that the application is hidden and cannot be stopped via the UI.

When constructing your process object, use a constructor overload that takes a ProcessStartInfo object. Set the WindowStyle property of this to ProcessWindowStyle.Hidden and the CreateNoWindow property to true:

ProcessStartInfo startInfo = new ProcessStartInfo("fortranApp.exe");
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.CreateNoWindow = true;

Process.Start(startInfo);

Of course, it will still appear in the process list and can be killed that way, but at least this will prevent any unintentional shutdown.

Oded
I want to be able to see the application though
Pieces
@Pieces - you can always start it minimized. Other then that, I don't now of a way to start a process and disable the window control buttons, if the application itself doesn't support it.
Oded
@Oded ok thanks
Pieces
Is it possible to start the process hidden, attach something to stdout to collect the messages generated by the Fortran program and pipe that to a display window on your C# program?
Peter M
Yes, use a streamReader on process object (property is called StandardOutput) that is returned from Process.Start.
jgauffin
A: 

You can try to use ProcessStartInfo and set the property CreateNoWindow to true and set WindowStyle to ProcessWindowStyle.Hidden. I haven't tried it myself but maybe you are lucky.

tobsen
+2  A: 

A solution that will take a decent amount of programming but can be done:

Write a separate program that intercepts the screen output of the program and sends it to your program somehow. Run this program in the hidden window, it turns around and runs the app and sends the output to your program.

At least parts of the interceptor are almost certainly going to have to be in assembly.

Edit: Redirecting stdout won't do it even if the program only writes to it--he wants the output displayed.

There are three things that might need to be intercepted:

Int 21h filesystem writes. These are the things that could be intercepted by redirecting stdout. Beware that some programs may write to a different handle number that actually represents the stdout file--look up the handle that's being written to in the program's handle table and compare it to the stdout entry (IIRC the second entry)--if they match it's actually screen output.

The second level is IIRC int 10h. There are several sub-calls that must be intercepted.

Finally, a program may do direct screen writes. Intercepting these would be a major pain, I wouldn't even consider trying it (you would have to basically rewrite the dos box.) Instead, frequently compare the screen memory with a saved copy looking for changes.

In all three cases at least parts of the routine are going to have to be written in assembly.

I have done the first, played a bit with the second but then I found that I could get by without doing it. I've never attempted the third.

Loren Pechtel
Why can't he just redirect the STDOUT from the process?
tster
+1 I think this is the best approach. I don't actually think it would require very much work, I know for sure the System.Diagnostics.Process class has properties for redirecting both the standard input AND output. He can then embed his app in some sort of a WPF or WinForms app and then make sure the user can't kill the host app.
Pandincus
+1 Redirecting stdio isn't difficult in .NET. It doesn't work for programs that directly write to the console, but those are rare.
Stephen Cleary
Unfortunately, intercepting STDOUT will probably not do it. Any program that maintains a screen format can't be intercepted by STDOUT. Only strictly console apps (and virtually all of these are utilities of some kind) can be intercepted that easily.
Loren Pechtel
I doubt that the average FORTRAN app is going to be writing to the console without using stdout.
Gabe
Even if it only uses stdout you still have to intercept that if you actually want to see the output.
Loren Pechtel