0

I found possible to use CMD window to start typical NET GUI application.
But not so clean, with some issues.

Here is my example code:

Public Class main_form

Private Declare Function AttachConsole Lib "kernel32.dll" (ByVal dwProcessId As Int32) As Boolean
Private Declare Function FreeConsole Lib "kernel32.dll" () As Boolean
Dim mykey As String = "A01F-FFB4-0402"


Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    If My.Application.CommandLineArgs.Count > 0 Then
        If AttachConsole(-1) Then
            Dim kill_Me As Boolean = False
            Dim cArgs() As String = GetCommandLineArgs()

            For c As Integer = 0 To cArgs.Length - 1
                cArgs(c) = cArgs(c).ToLower()

                If cArgs(c) = "getkey" Then
                    Console.WriteLine(mykey)
                    kill_Me = True
                End If
            Next

            FreeConsole()
            If kill_Me Then End 

            If (MessageBox.Show( _
                "Asked command not present." & NewLine & "Start program with GUI normally?", "", _
                 MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) = _
                 DialogResult.Cancel) _
            Then End
        End If
    End If

Please ignore security issues, this is just an example. Like people here concludes problem is in terminating console. Here are approach with sending key "ENTER" to it but this is obviously not good solution.

If I start example program from CMD window with: c:\mydir>myprogram.exe getkey|more then console behaves more "natural" than without switch "more".

1) But, if I start a program with c:\mydir>myprogram.exe getkey: is it possible with VBNET to add keyword "|more" to commandline argument "getkey" before execution so program will execute "getkey|more" instead of only "getkey"?

2) Is it acceptable to terminate GUI program with just command "End" in form's _Load handler like is showed in example? I try Application.Exit() and Me.Close() where program don't behaves well.

Community
  • 1
  • 1
Wine Too
  • 4,515
  • 22
  • 83
  • 137

1 Answers1

2

Your application (be it .Net or native, doesn't matter) can be a console application or GUI application, but not both. This has been discussed before by smarter people than me: How do I write a program that can be run either as a console or a GUI application:

Each PE application contains a field in its header that specifies which subsystem it was designed to run under. You can say IMAGE_SUBSYSTEM_WINDOWS_GUI to mark yourself as a Windows GUI application, or you can say IMAGE_SUBSYSTEM_WINDOWS_CUI to say that you are a console application. If you are GUI application, then the program will run without a console.

The subsystem determines how the kernel prepares the execution environment for the program. If the program is marked as running in the console subsystem, then the kernel will connect the program's console to the console of its parent, creating a new console if the parent doesn't have a console. (This is an incomplete description, but the details aren't relevant to the discussion.) On the other hand, if the program is marked as running as a GUI application, then the kernel will run the program without any console at all.

So if you have a GUI application then you cannot connect the application stdin/stderr to your console, so pipes will not work, ergo things like cat, more, less, tee are all a no-go for a GUI application. Not to mention that the CMD console will not wait for your application.

Try not to cheat. Use a GUI for GUI, use a console app for console. Share common code in libs.

Community
  • 1
  • 1
Remus Rusanu
  • 288,378
  • 40
  • 442
  • 569
  • Interesting, but what if someone would like to "debug" his "release" application by watching what happens in program and looking to such attached background console what program writes? Is this a cheating? What if someone need "that kind" of console for service needs? After all, question is concrete and asks for help in described situation. – Wine Too Oct 25 '13 at 09:29
  • If you want to log from GUI, log to file. Hello, [log4net](http://logging.apache.org/log4net/). – Remus Rusanu Oct 25 '13 at 09:39
  • Well, your answer is meaningful. But I have on mind really "service" situation where I have need to get some info from program on machine where minimal set of software is installed or where may be a problem with GUI or where I have to know "what program can't pass" or similar... There such console may be useful. Can you reply at least on second question? – Wine Too Oct 25 '13 at 09:54
  • Whether is safe to terminate an app by `End`ing the 'Main' form is entirely dependent on the app. You already tried `Exit` and `Close` and say the application 'doesn't behave well`. Most apps I know behave perfectly well when Exit is called (they exit). You are venturing off the beaten path vis-a-vis behavior like 'console' vs. 'GUI', debugging, logging etc, so you are pretty much on your own. Did you consider alternatives like low overhead debuggers, eg. `ntsd.exe`? – Remus Rusanu Oct 25 '13 at 10:04