0

I have a windows forms application with a working GUI. However I want the application to be able to be started and used in a command-line interface aswell as a regular GUI application. When the application is started in an CLI the GUI shall not be used an instead relevant information will be written to the CLI-application. What I need to do this is a way to detect if the application (its exe file) is started in a CLI-application such as the regular windows CMD or started in a normal fashion such as clicking the exe file in the file explorer or using a desktop shortcut.

Preferably the detection should be done in the main method of the application such as

static class Program
    {
        [STAThread]
        static void Main()
        {
            //if(application not started in a CLI-application) 
                 Application.Run(new DriverToolApplicationContext());
             //else 
                 //Console.writeLine("Application started in CLI-application");
        }

    }

How is this detection best implemented? I preferably do not want to put any arguments in the main method.

MarkusAnd
  • 750
  • 7
  • 21
  • "best implemented"? It isn't, you shouldn't do it, it's going to be very difficult for you to do this correctly. Also, for your program to *easily* write things to the console, it should be built as a console application, which means that a double-click on its icon will also have a console because the program said it needed one. If, on the other hand, you compile it as a windows application, and thus not get a console, it will not be easy to write to the current console if you actually open it from a terminal window. You're going to struggle with this, my advice, don't do it. – Lasse V. Karlsen Jun 22 '20 at 07:54
  • 1
    https://stackoverflow.com/questions/19471527/c-sharp-application-that-can-be-run-from-console-but-does-not-create-a-window/19472762#19472762 – Hans Passant Jun 22 '20 at 08:04
  • @LasseV.Karlsen are you suggesting that I create two seperate applications? One console app and one windows app? – MarkusAnd Jun 22 '20 at 08:43
  • 1
    Yes, because attaching to an existing console is not an easy thing to do with .NET. – Lasse V. Karlsen Jun 22 '20 at 09:22
  • 1
    You have two problems, 1) detecting whether it was started from an existing terminal window or not, and 2) how to get one process to correctly behave as a windows application or as a console application. I haven't even considered how to detect the existance of the terminal window, but the dual behavior is going to be problematic enough that I would simply find a different way of doing it. The dual executables, linking to the same class libraries with the actual code is a much simpler solution. – Lasse V. Karlsen Jun 22 '20 at 09:24
  • You can see an existing question here - https://stackoverflow.com/questions/338951/output-to-command-line-if-started-from-command-line#339216 - I think yours is a duplicate of this because as far as I know, nothing has really changed regarding this. – Lasse V. Karlsen Jun 22 '20 at 09:27
  • I see, thank you for your time and tips they have been very useful! – MarkusAnd Jun 22 '20 at 09:33

2 Answers2

6

I think you'll struggle without arguments tbh; most apps I can think of that have this dual mode operation bundle as two exes, a gui one and a command line one (and one maybe uses the other)

It really is the simplest way to just have rules:

  • if the application is started with no arguments, print(and/or messagebox.show) the command line arguments and quit
  • if the app is started with eg /gui argument (baked into the windows shortcut) it runs as gui
  • if the app is started with other arguments for command line operation, proceed as per those arguments

You can vary these of course, maybe you would have:

  • if the application is started with no arguments, run as gui
  • if the app is started with eg /? argument print the command line arguments and quit
  • if the app is started with other arguments for command line operation, proceed as per those arguments

I make this recommendation chiefly because, to be really useful as a command line app an app probably needs to take arguments from the command line, so you can use their presence or absence to infer where the app was started from. It's not perfect, of course - a shortcut can "start from windows" but pass arguments that will make i the app think it was command line, but where I'm getting to is that generally that doesn't matter because this question is not so much about "where it was started from?" as "does the app have enough info to do its work or must it ask the user for info?"

Caius Jard
  • 72,509
  • 5
  • 49
  • 80
  • Perhaps I underestimated the difficulty of doing this without any arguments, I think this method will work well. Thanks! – MarkusAnd Jun 22 '20 at 08:45
1

To do this without command line parameters you would need to be able to find what process launches your one. This question shows how to find the parent process id Finding parent process ID on Windows However, if you launch a program from command prompt it's parent process id is not the one that the command prompt has. You might have to do something that reads event log and after all that realise that what you need will require admin rights. The above suggestion to use command arguments is probably a better solution but I'd be curious to see if it can be done without them.