C# Console app with hidden window and user input

D

Dilip

Hi All

I have a server based C# console application. This application must
hide its console window when its launched out on the field. So I
dutifully P/Invoke'd FindWindow/ShowWindow combination to hide the
console window at launch time.

The application (for legacy reasons) hangs around by waiting on an old-
fashioned Console.ReadLine() statement.

How can such an application be terminated externally? By externally I
mean via a batch file or script or some such? Launching is the easy
part. How does a hidden console window recieve keyboard input so that
the shut down code can execute?

Or am I going about this the wrong way?
 
J

Jon Skeet [C# MVP]

Dilip said:
I have a server based C# console application. This application must
hide its console window when its launched out on the field. So I
dutifully P/Invoke'd FindWindow/ShowWindow combination to hide the
console window at launch time.

The application (for legacy reasons) hangs around by waiting on an old-
fashioned Console.ReadLine() statement.

How can such an application be terminated externally? By externally I
mean via a batch file or script or some such? Launching is the easy
part. How does a hidden console window recieve keyboard input so that
the shut down code can execute?

Or am I going about this the wrong way?

Why have you made it a console app if you don't want a console? Just
create a Windows Service or a simple Windows Forms app that happens not
to display any forms.
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

Dilip said:
Hi All

I have a server based C# console application. This application must
hide its console window when its launched out on the field. So I
dutifully P/Invoke'd FindWindow/ShowWindow combination to hide the
console window at launch time.

Why you have a console app that have no interface?
What do you mean with "server based"? Does it means that the app will run in
a server and is probably nobody is logged on it?

Did you look into making it a windows service?

The application (for legacy reasons) hangs around by waiting on an old-
fashioned Console.ReadLine() statement.

If this is a new app, what is going on with the "legacy" part?
 
D

Dilip

Why have you made it a console app if you don't want a console? Just
create a Windows Service or a simple Windows Forms app that happens not
to display any forms.

I should've prefaced my question with all of this.

The application *was* a service but strangely it also launches a
complex Winforms based application (now please don't ask me why or how
-- thats just the way it is). Under Vista however Services cannot
interact with the desktop (as they run on Session 0 which is different
from the ones UI apps run) and hence cannot launch another application
that displays UI.

So I am trying to work backwards by converting that application to a
console app but w/the console window hidden.

The problem I am running into happens when I want to shut it down.
Because its now hidden I don't know how to shut it down gracefully.

Given the constraints is there any way to do it from an external
script? It has to be an external batch file or something that
probably has a short cut to it in the Start menu.

I am open to approaches that don't rely on Console.ReadLine().

Maybe I could create an event and wait on it.
From a totally different tiny app2 that can be launched from the
script once again I could probably do a SetEvent on the event thus
opened and get the code to shut down gracefully.

Will that work?
 
D

Doug Semler

I should've prefaced my question with all of this.

The application *was* a service but strangely it also launches a
complex Winforms based application (now please don't ask me why or how
-- thats just the way it is). Under Vista however Services cannot
interact with the desktop (as they run on Session 0 which is different
from the ones UI apps run) and hence cannot launch another application
that displays UI.

If it is a service, I am presuming that it does other things than
launch the windows form application. Killing it might be a bad idea,
especially if it needs to be "always on" or that the windows form
application is communicating with the service. When you say launch do
you mean "creates another process via another executable" or just
"instantiates Forms and shows them". If it is the former, then you
should just make the windows form application launchable by the user.
If it is the latter, you should really think about breaking out the
forms app into a second execuatble and communicating with the service
via remoting (or other form of IPC).
So I am trying to work backwards by converting that application to a
console app but w/the console window hidden.

The problem I am running into happens when I want to shut it down.
Because its now hidden I don't know how to shut it down gracefully.

Given the constraints is there any way to do it from an external
script? It has to be an external batch file or something that
probably has a short cut to it in the Start menu.

I am open to approaches that don't rely on Console.ReadLine().

Maybe I could create an event and wait on it.>From a totally different tiny app2 that can be launched from the

script once again I could probably do a SetEvent on the event thus
opened and get the code to shut down gracefully.

Will that work?

You're making it more complicated than it needs to be. If the console
app is done with its work, you should just let it exit. The only
reason to require a "Console.Readline()" is to allow a user to read
whatever is on the screen or to help with debugging. Since you no
longer have a console, there is NO reason that you should have a
readline. If the "console app" is doing stuff in background threads,
you can set the IsBackground property of those threads to false (which
is the default, I believe). The app won't exit until all the
foreground threads have completed their work. Also, as others have
suggested, make it a windows app that just doesn't show a form rather
than a console app. This way you don't have to do all convoluted
logic to hide the window...
 
J

Jon Skeet [C# MVP]

Dilip said:
I should've prefaced my question with all of this.

The application *was* a service but strangely it also launches a
complex Winforms based application (now please don't ask me why or how
-- thats just the way it is). Under Vista however Services cannot
interact with the desktop (as they run on Session 0 which is different
from the ones UI apps run) and hence cannot launch another application
that displays UI.

So I am trying to work backwards by converting that application to a
console app but w/the console window hidden.

But why not a Windows Forms app that doesn't show any forms? That
sounds like the way forward.

If you're dead set on using a console app, however, you could kill it
by listening on a local socket, and dying whenever something connects
to that socket and sends an appropriate packet.
 
W

Willy Denoyette [MVP]

Dilip said:
I should've prefaced my question with all of this.

The application *was* a service but strangely it also launches a
complex Winforms based application (now please don't ask me why or how
-- thats just the way it is). Under Vista however Services cannot
interact with the desktop (as they run on Session 0 which is different
from the ones UI apps run) and hence cannot launch another application
that displays UI.

So I am trying to work backwards by converting that application to a
console app but w/the console window hidden.

The problem I am running into happens when I want to shut it down.
Because its now hidden I don't know how to shut it down gracefully.

Given the constraints is there any way to do it from an external
script? It has to be an external batch file or something that
probably has a short cut to it in the Start menu.

I am open to approaches that don't rely on Console.ReadLine().

Maybe I could create an event and wait on it.
script once again I could probably do a SetEvent on the event thus
opened and get the code to shut down gracefully.

Will that work?


The console application has to be started by a "human being", right?, why
not let him start the Windows application instead?

Willy.
 
D

Dilip

But why not a Windows Forms app that doesn't show any forms? That
sounds like the way forward.

You are not going to believe this but the only reason why this app was
made a service was because the original team did not want it popping
up a console window. In all respects this app was born as a console
app and it does nothing that would bestow the boon of being a service
on it (for example it doesnt and cannot run while there is no user
logged on). So in reality, when the app is under development we
usually use it as a console app which just waits on a console.readline
statement. The reason its waiting on that statement is because after
the user hits enter (or whatever) the app executes clean up code AND
pulls down the UI app (that it launched on start up) at the same
time. On deployment it gets installed as a service and an external
batch script just starts and stops it using the SCM. OnStart launches
the UI app, OnStop executes clean up code and shuts down the UI app.

Now, you see where I am going? This app is *already* a console app.
I don't want to get into the hassle of converting it into a winforms
app. I wanted to retain it as a console app but find a way to shut it
down gracefully while the console window remains hidden.
If you're dead set on using a console app, however, you could kill it
by listening on a local socket, and dying whenever something connects
to that socket and sends an appropriate packet.

I guess I could do this too but don't you like the
EventWaitHandle.OpenExisting idea?
 
J

Jon Skeet [C# MVP]

Dilip said:
You are not going to believe this but the only reason why this app was
made a service was because the original team did not want it popping
up a console window. In all respects this app was born as a console
app and it does nothing that would bestow the boon of being a service
on it (for example it doesnt and cannot run while there is no user
logged on). So in reality, when the app is under development we
usually use it as a console app which just waits on a console.readline
statement. The reason its waiting on that statement is because after
the user hits enter (or whatever) the app executes clean up code AND
pulls down the UI app (that it launched on start up) at the same
time. On deployment it gets installed as a service and an external
batch script just starts and stops it using the SCM. OnStart launches
the UI app, OnStop executes clean up code and shuts down the UI app.

Now, you see where I am going? This app is *already* a console app.
I don't want to get into the hassle of converting it into a winforms
app. I wanted to retain it as a console app but find a way to shut it
down gracefully while the console window remains hidden.

Um, there's no hassle at all. You change the project type - it takes
about 10 seconds to do.
I guess I could do this too but don't you like the
EventWaitHandle.OpenExisting idea?

That should work, yeah - they're pretty similar solutions.
 
D

Doug Semler

You are not going to believe this but the only reason why this app was
made a service was because the original team did not want it popping
up a console window. In all respects this app was born as a console
app and it does nothing that would bestow the boon of being a service
on it (for example it doesnt and cannot run while there is no user
logged on). So in reality, when the app is under development we
usually use it as a console app which just waits on a console.readline
statement. The reason its waiting on that statement is because after
the user hits enter (or whatever) the app executes clean up code AND
pulls down the UI app (that it launched on start up) at the same
time. On deployment it gets installed as a service and an external
batch script just starts and stops it using the SCM. OnStart launches
the UI app, OnStop executes clean up code and shuts down the UI app.

Now, you see where I am going? This app is *already* a console app.
I don't want to get into the hassle of converting it into a winforms
app. I wanted to retain it as a console app but find a way to shut it
down gracefully while the console window remains hidden.


Move your initialization and cleanup code into the windows application
that is launched. Get rid of the console app, and require the user to
double click the windows application instead.

Or, if the forms are actually in the console application, change the
project to make it compile as a windows application.

Either way, Problem solved.

I guess I could do this too but don't you like the
EventWaitHandle.OpenExisting idea?

I think it was more of a jab at your making this way more complicated
than it needs to be.
 
D

Dilip

Move your initialization and cleanup code into the windows application
that is launched. Get rid of the console app, and require the user to
double click the windows application instead.

See.. now you are treating me like a moron :) I explained the
problem in a way that wouldn't pull in a lot of needless information
that would definitely be irrelevant to you. There is a reason why
that console app exists and its not to simply launch the UI app. it
does a whole bunch of other things that if I start writing down will
obscure the problem completely.
I think it was more of a jab at your making this way more complicated
than it needs to be.- Hide quoted text -

Well.. I know Jon doesn't jab. I have been lurking around in this
newsgroup too long to know that for a fact.
 
D

Doug Semler

See.. now you are treating me like a moron :) I explained the
problem in a way that wouldn't pull in a lot of needless information
that would definitely be irrelevant to you. There is a reason why
that console app exists and its not to simply launch the UI app. it
does a whole bunch of other things that if I start writing down will
obscure the problem completely.

Actually, you have changed the problem domain entirely. However, based
on your current explanation you have the following:

Application A
Initializes something (irrelevant what it is)
Launches App B
Waits for a signal (currently Console.ReadLine)
Brings down application B
Cleans up something (again irrelevant)

Application B
"Complicated" Windows Application that does something.

I have serious issues with this design. For example, what happens
when App A is signalled to end prematurely and brings down app B? How
are you bringing down App B? Process.Kill? That is not *a good
thing*. What happens if a user starts Application B without having
started Application A? What happens if Application B crashes? Are
you depending upon some sort of double clicked icon to signal app a to
shut down? (i.e. do I have to go to the start menu to shut down
application A?) Since killing App a kills app b, that means that app
b shutsdown unexpectedly. What happens if I close application B
without shutting down app a?

Why do you NOT think it would be better to design it thusly, unless
(which you haven't stated yet) you do not have the source code for the
windows application:

Application:
Initializes Something
Shows Complicated Main Form (Application.Run(Form))
Cleans up something after return from Application.Run()

If you don't have the source for app b, as has been said, you can make
a console application a non-console application by changing the
project properties to be Windows Application. Then, in the Main
method you can do the following:

Application A:
Initilizes something
Process b = Process.Start(ApplicationB path)
b.WaitForExit()
Cleansup something.

That way, when the user exits app b, app a will automatically shut
down itself. And by virtue of making it a windows application, you
lose the console window....
Well.. I know Jon doesn't jab. I have been lurking around in this
newsgroup too long to know that for a fact.

I think you missed the implied smilie on the end of that :) Besides,
Jon has it all wrong, the best way would be to use memory mapped
files :)
 
D

Dilip

Actually, you have changed the problem domain entirely. However, based
on your current explanation you have the following:

Application A
Initializes something (irrelevant what it is)
Launches App B
Waits for a signal (currently Console.ReadLine)
Brings down application B
Cleans up something (again irrelevant)

Application B
"Complicated" Windows Application that does something.

I have serious issues with this design.

I need to bring this thread to a close but since you took so much time
to type up your opinion I would be insulting you by not responding. I
will keep this short. This is the way this application has been
written and most of your concerns have been handled one way or the
other. I don't know why its written this way and I am pretty sure in
hindsight I myself would embark on thousand different ways of doing
things. Its a little too late in the day to do any major
rearchitecting since the project has been around for 5 years now.

as things stand my task is to get it running on Vista and whether I
like it or not I *have* to stick to that :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top