Converting a Console app to a Windows app - pitfalls to watch out for

I've now seen several articles that discuss converting a Console app to a Windows app without addressing outstanding issues that need to be addressed. I thought this would be a good place to do so.

But first, why did the authors intend to do this? Seems that when starting up a Console app, even if you try to hide the Console window, there is a brief (and annoying) flash.

I suggested the following:

Apparently, there is a warning in the Microsoft docs suggesting to avoid GetConsoleWindow() in that this wont work in future version in Remote Desktop/Terminal Services. 

I would counter that if that's the concern, converting to a Windows app makes things worse because stdin, stdout and stderr are closed, which make the application interaction impossible.

So let's follow this then and see what issues need to be addressed if we pursue this course of action:

1) stdin, stdout and stderr are sent to devnull. This isn't just a question of command line parsing, many console apps act as "filters" (think Unix/Linux type apps like grep). These need to be rewritten to handle input/output.

2) That being said, a Console app allocates a Console window. A Windows app does not, but can attach to one. Important when writing a Console app that interacts with Remote Desktop/Terminal Server.

3) Windows app always start in an STA thread (they have to for the Dispatcher to work). Console apps start in an MTA thread. This matter is Console app create COM objects, as the default behavior would rely on MTA cross-COM calls. Suddenly finding oneself in an STA thread would create opportunities for errors and memory corruption. The COM objects would either need to be converted to run in an STA thread, or would require marshaling code i.e. this becomes a DCOM app which adds a host of complexity.

Even if you don't explicitly create COM object, many OS calls are wrappers around COM objects e.g. Shell services for interacting with the underlying file system which would properly show in the Windows Explorer.

4) Thread creation would by default be MTA, since the foreground is MTA in a Console app. Once changed to a Windows app, these additional threads need to change how communicate to the foreground thread. Same issues apply as in (3).

Can all of this be addressed? Of course, if you, Joe/Jane developer are careful and judicious about the approach. That's what's missing from the article, and should be added to avoid error prone code and apps from be let out into the wild.

My suggestion, however, would be instead to convert the Console application to a Windows Service. In addition to solving this in a best practices approach, it also allows the developer to add fine grained privilege settings as well.



Popular posts from this blog

Representing C/C++ unions and bitfields in C#

Implementing the try/catch/finally pattern in C++ using lambdas, or why cant this be as easy as it is in C#?

Dispatch? I'd like to make a call. The difference between Synchronization Context, Task Scheduler and Dispatcher