Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Show a hidden console again?

Show a hidden console again?

Scheduled Pinned Locked Moved C#
cssdesignlinuxtutorialquestion
11 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Don Rolando

    Hi everyone, we have an GUI application that starts and observes several console processes. Because it can be lots of processes, we are starting these console applications hidden:

    Process process = new Process();
    process.StartInfo.FileName = dir + @"\ConsoleApp.exe";
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.CreateNoWindow = true;
    process.Start();

    So far so good, no shell is showing up! But if the user closes the user interface (which started these processes) all the console applications are still running. Since they should finish their job, this is more or less ok. But we would like to show each console again, so the user could stop them if necessary or watch output in each shell himself. Any idea how to show the console applications again? The preferred approach would be that each console application can show itself. (So they would pop up again even if the GUI simply crashed) I have looked into the process information, but the MainWindowHandle property is set to null for the console applications, so I can't use it to show the shell. That's also true for any other combination of startinfo properties which lead to a hidden console. In contrast, Spy++ shows a hidden window for my hidden console app! So how to obtain the (still hidden) window's handle? Or any other idea how to show these hidden consoles again? Cheers, Roland

    V Offline
    V Offline
    V 0
    wrote on last edited by
    #2

    Try windows messages. that gets messages accross applications easily AND you let the application itself handle his own properties. hope this helps.

    V.

    D 1 Reply Last reply
    0
    • V V 0

      Try windows messages. that gets messages accross applications easily AND you let the application itself handle his own properties. hope this helps.

      V.

      D Offline
      D Offline
      Don Rolando
      wrote on last edited by
      #3

      Could you please go into details a little more? What window message would you send to whome? ShowWindow is also just sending SW_SHOW in the end, but I would need to know the window handle of the console application before I can send it there... Cheers, Roland

      V 1 Reply Last reply
      0
      • D Don Rolando

        Could you please go into details a little more? What window message would you send to whome? ShowWindow is also just sending SW_SHOW in the end, but I would need to know the window handle of the console application before I can send it there... Cheers, Roland

        V Offline
        V Offline
        V 0
        wrote on last edited by
        #4

        Look here[^] key words were C# send window message in google.

        V.

        D 1 Reply Last reply
        0
        • V V 0

          Look here[^] key words were C# send window message in google.

          V.

          D Offline
          D Offline
          Don Rolando
          wrote on last edited by
          #5

          Oh funny reply, dude! Was the question how to send window messages in general? As I said before, you'd have to know who is the recipient for that message, and actually THAT is the problem. A hidden application has no idea about it's main window's hwnd. And a console application cannot set it's window title to make other apps find it by FindWindow with given title.

          V 1 Reply Last reply
          0
          • D Don Rolando

            Oh funny reply, dude! Was the question how to send window messages in general? As I said before, you'd have to know who is the recipient for that message, and actually THAT is the problem. A hidden application has no idea about it's main window's hwnd. And a console application cannot set it's window title to make other apps find it by FindWindow with given title.

            V Offline
            V Offline
            V 0
            wrote on last edited by
            #6

            Don't be so impolite. And I gather you haven't understood my reply, at all. I guess you'll have to figure it out for yourself then. I'm sorry I wasn't able to make it more clearer to you. :mad:

            V.

            D 1 Reply Last reply
            0
            • V V 0

              Don't be so impolite. And I gather you haven't understood my reply, at all. I guess you'll have to figure it out for yourself then. I'm sorry I wasn't able to make it more clearer to you. :mad:

              V.

              D Offline
              D Offline
              Don Rolando
              wrote on last edited by
              #7

              Sorry, but from my point of view your post was already inpolite. ;P I know how to google and how to send messages, I am no noob. But if you have no window handle as recipient, you will never send messages anywhere. And the page you linked uses Process' MainWindowHandle property which is always NULL for hidden windows. (As written in my initial post, maybe you have only scanned the first lines of it.) No window handle, no chance to send the message. Seems I have really to enumerate over all windows and find the hidden window that belongs to the process... what a hack...

              1 Reply Last reply
              0
              • D Don Rolando

                Hi everyone, we have an GUI application that starts and observes several console processes. Because it can be lots of processes, we are starting these console applications hidden:

                Process process = new Process();
                process.StartInfo.FileName = dir + @"\ConsoleApp.exe";
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.CreateNoWindow = true;
                process.Start();

                So far so good, no shell is showing up! But if the user closes the user interface (which started these processes) all the console applications are still running. Since they should finish their job, this is more or less ok. But we would like to show each console again, so the user could stop them if necessary or watch output in each shell himself. Any idea how to show the console applications again? The preferred approach would be that each console application can show itself. (So they would pop up again even if the GUI simply crashed) I have looked into the process information, but the MainWindowHandle property is set to null for the console applications, so I can't use it to show the shell. That's also true for any other combination of startinfo properties which lead to a hidden console. In contrast, Spy++ shows a hidden window for my hidden console app! So how to obtain the (still hidden) window's handle? Or any other idea how to show these hidden consoles again? Cheers, Roland

                A Offline
                A Offline
                Alan N
                wrote on last edited by
                #8

                There was a post on MSDN about this a while ago, How to obtain a Console Window Handle[^] which uses FindWindow to look for a known window title. It seems ok for Windows XP and I wrote a quick test (with no error checking on the Windows API calls).

                public partial class ConsoleControllerForm : Form {
                [DllImport("user32.dll")]
                [return: MarshalAs(UnmanagedType.Bool)]
                private static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);

                [DllImport("user32.dll")]
                private static extern IntPtr FindWindowW(
                [In] [MarshalAs(UnmanagedType.LPWStr)] String lpClassName,
                [In] [MarshalAs(UnmanagedType.LPWStr)] String WindowName);

                private const String KnownConsoleTitle = "TestApp";
                private IntPtr handle;

                public ConsoleControllerForm() {
                InitializeComponent();
                }

                private void StartBtn_Click(object sender, EventArgs e) {
                StartProcess();
                FindCmd();
                }

                private void FindCmd() {
                handle = FindWindowW(null, KnownConsoleTitle);
                ShowBtn.Enabled = handle != IntPtr.Zero;
                }

                private void ShowBtn_Click(object sender, EventArgs e) {
                ShowWindow(handle, 1); // ShowNormal = 1
                }

                private static void StartProcess() {
                ProcessStartInfo psi = new ProcessStartInfo();
                psi.FileName = @"TestApp.exe";
                psi.UseShellExecute = true;
                psi.CreateNoWindow = false;
                psi.WindowStyle = ProcessWindowStyle.Hidden;
                Process p = Process.Start(psi);
                // Allow process to start. Can't use WaitForIdleInput
                Thread.Sleep(1000);
                }
                }

                Note the ProcessStartInfo properties are the only combination for which the subsequent ShowWindow actually shows the window and that TestApp.exe explicitly sets it's title to "TestApp" so I know what to look for with FindWindow. I doubt this approach will solve your problem completely but hopefully it's given you a start. Alan.

                D 1 Reply Last reply
                0
                • D Don Rolando

                  Hi everyone, we have an GUI application that starts and observes several console processes. Because it can be lots of processes, we are starting these console applications hidden:

                  Process process = new Process();
                  process.StartInfo.FileName = dir + @"\ConsoleApp.exe";
                  process.StartInfo.UseShellExecute = false;
                  process.StartInfo.CreateNoWindow = true;
                  process.Start();

                  So far so good, no shell is showing up! But if the user closes the user interface (which started these processes) all the console applications are still running. Since they should finish their job, this is more or less ok. But we would like to show each console again, so the user could stop them if necessary or watch output in each shell himself. Any idea how to show the console applications again? The preferred approach would be that each console application can show itself. (So they would pop up again even if the GUI simply crashed) I have looked into the process information, but the MainWindowHandle property is set to null for the console applications, so I can't use it to show the shell. That's also true for any other combination of startinfo properties which lead to a hidden console. In contrast, Spy++ shows a hidden window for my hidden console app! So how to obtain the (still hidden) window's handle? Or any other idea how to show these hidden consoles again? Cheers, Roland

                  P Offline
                  P Offline
                  PIEBALDconsult
                  wrote on last edited by
                  #9

                  If your GUI app crashes, I see no way for it to even try to do this beforehand. Are you also developing the console apps? If so, maybe the console app can monitor the existence of the GUI app and hide and reshow itself on its own?

                  D 1 Reply Last reply
                  0
                  • A Alan N

                    There was a post on MSDN about this a while ago, How to obtain a Console Window Handle[^] which uses FindWindow to look for a known window title. It seems ok for Windows XP and I wrote a quick test (with no error checking on the Windows API calls).

                    public partial class ConsoleControllerForm : Form {
                    [DllImport("user32.dll")]
                    [return: MarshalAs(UnmanagedType.Bool)]
                    private static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);

                    [DllImport("user32.dll")]
                    private static extern IntPtr FindWindowW(
                    [In] [MarshalAs(UnmanagedType.LPWStr)] String lpClassName,
                    [In] [MarshalAs(UnmanagedType.LPWStr)] String WindowName);

                    private const String KnownConsoleTitle = "TestApp";
                    private IntPtr handle;

                    public ConsoleControllerForm() {
                    InitializeComponent();
                    }

                    private void StartBtn_Click(object sender, EventArgs e) {
                    StartProcess();
                    FindCmd();
                    }

                    private void FindCmd() {
                    handle = FindWindowW(null, KnownConsoleTitle);
                    ShowBtn.Enabled = handle != IntPtr.Zero;
                    }

                    private void ShowBtn_Click(object sender, EventArgs e) {
                    ShowWindow(handle, 1); // ShowNormal = 1
                    }

                    private static void StartProcess() {
                    ProcessStartInfo psi = new ProcessStartInfo();
                    psi.FileName = @"TestApp.exe";
                    psi.UseShellExecute = true;
                    psi.CreateNoWindow = false;
                    psi.WindowStyle = ProcessWindowStyle.Hidden;
                    Process p = Process.Start(psi);
                    // Allow process to start. Can't use WaitForIdleInput
                    Thread.Sleep(1000);
                    }
                    }

                    Note the ProcessStartInfo properties are the only combination for which the subsequent ShowWindow actually shows the window and that TestApp.exe explicitly sets it's title to "TestApp" so I know what to look for with FindWindow. I doubt this approach will solve your problem completely but hopefully it's given you a start. Alan.

                    D Offline
                    D Offline
                    Don Rolando
                    wrote on last edited by
                    #10

                    Hi Alan, thanks for your reply! At the moment I really make use of a combination of EnumWindows and GetWindowThreadProcessId to get my own (hidden) window's handle within the console application. But I am not happy about enumerating over all windows. FindWindow was also my first thought... the problem was that I had no clue what the title is. The shell usually shows the console application's full path in the title. Having multiple instances running, this can be quite difficult to find a specific one. But you made me think about the window title again, because you really hardcoded a title for a console application. First I thought I could not change it from within the console application itself in C#, since MainWindowTitle is read-only. But then I found the following API method:

                    [DllImportAttribute("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
                    public static extern bool SetConsoleTitle(IntPtr lpConsoleTitle);

                    In this case I can easily set the window title; either by passing it as parameter along with ProcessStartInfo, or simply generating it within the console itself. Thanks for thought-provoking impulse. :) Cheers, Roland

                    1 Reply Last reply
                    0
                    • P PIEBALDconsult

                      If your GUI app crashes, I see no way for it to even try to do this beforehand. Are you also developing the console apps? If so, maybe the console app can monitor the existence of the GUI app and hide and reshow itself on its own?

                      D Offline
                      D Offline
                      Don Rolando
                      wrote on last edited by
                      #11

                      Yes, we create both, the GUI and the Console Apps. The latter one can be executed manually or started through the UI (invisible). So we are actually realy monitoring the UI, but had no (good) idea how to make the console show itself when the GUI was gone. But as a result of Alan's thought-provoking impulse I have an idea how to do this now. :) Cheers, Roland

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups