Показать консоль в приложении Windows?

Мне нравится этот способ, определение метода среза и передача лямбда-предиката:

def slice_when(predicate, iterable):
  i, x, size = 0, 0, len(iterable)
  while i < size-1:
    if predicate(iterable[i], iterable[i+1]):
      yield iterable[x:i+1]
      x = i + 1
    i += 1
  yield iterable[x:size]

tst = [1,3,4,6,8,22,24,25,26,67,68,70,72]
slices = slice_when(lambda x,y: y - x > 2, tst)
print(list(slices))
#=> [[1, 3, 4, 6, 8], [22, 24, 25, 26], [67, 68, 70, 72]]

Полезно во многих случаях.

80
задан Jeffrey Bosboom 7 May 2015 в 22:10
поделиться

7 ответов

То, что Вы хотите сделать, не возможно нормальным способом. Был подобный вопрос , так посмотрите на ответы .

Тогда существует также безумный подход (сайт вниз - копируют доступный здесь. ) записанный Jeffrey Knight :

Вопрос: Как я создаю приложение, которое может работать или в GUI (окна) режим или в командной строке / консольный режим?

На поверхности его, это казалось бы легким: Вы создаете Консольное приложение, добавляете форму окон к нему, и Вы являетесь выключенными и рабочими. Однако существует проблема:

проблема: Если Вы работаете в режиме GUI, Вы заканчиваете и с окном и с противной консолью, скрывающейся в фоновом режиме, и у Вас нет способа скрыть его.

то, Что люди, кажется, хотят, является истинным земноводным приложением, которое может работать гладко в любом режиме.

при разрушении его здесь существует на самом деле четыре варианта использования:

User starts application from existing cmd window, and runs in GUI mode
User double clicks to start application, and runs in GUI mode
User starts application from existing cmd window, and runs in command mode
User double clicks to start application, and runs in command mode.

я отправляю код, чтобы сделать это, но с протестом.

я на самом деле думаю, что этот вид подхода выполнит Вас в намного большую проблему в будущем, чем это стоит. Например, у Вас должно будет быть два различных UIs' - один для GUI и один для команды / оболочка. Вы оказываетесь перед необходимостью создавать некоторый странный центральный логический механизм, что краткие обзоры от GUI по сравнению с командной строкой, и он просто собирается стать странным. Если бы это был я, я отступил бы и думал бы о том, как это будет использоваться на практике, и стоит ли этот вид переключения мод работы. Таким образом, если некоторый особый случай не призвал к нему, я не буду использовать этот код сам, потому что, как только я сталкиваюсь с ситуациями, где мне нужны вызовы API, чтобы сделать что-то, я склонен останавливаться и спрашивать меня, "я сверхусложняю вещи?".

Вывод type=Windows Приложение

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using Microsoft.Win32;

namespace WindowsApplication
{
    static class Program
    {
        /*
    DEMO CODE ONLY: In general, this approach calls for re-thinking 
    your architecture!
    There are 4 possible ways this can run:
    1) User starts application from existing cmd window, and runs in GUI mode
    2) User double clicks to start application, and runs in GUI mode
    3) User starts applicaiton from existing cmd window, and runs in command mode
    4) User double clicks to start application, and runs in command mode.

    To run in console mode, start a cmd shell and enter:
        c:\path\to\Debug\dir\WindowsApplication.exe console
        To run in gui mode,  EITHER just double click the exe, OR start it from the cmd prompt with:
        c:\path\to\Debug\dir\WindowsApplication.exe (or pass the "gui" argument).
        To start in command mode from a double click, change the default below to "console".
    In practice, I'm not even sure how the console vs gui mode distinction would be made from a
    double click...
        string mode = args.Length > 0 ? args[0] : "console"; //default to console
    */

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool AllocConsole();

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool FreeConsole();

        [DllImport("kernel32", SetLastError = true)]
        static extern bool AttachConsole(int dwProcessId);

        [DllImport("user32.dll")]
        static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll", SetLastError = true)]
        static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);

        [STAThread]
        static void Main(string[] args)
        {
            //TODO: better handling of command args, (handle help (--help /?) etc.)
            string mode = args.Length > 0 ? args[0] : "gui"; //default to gui

            if (mode == "gui")
            {
                MessageBox.Show("Welcome to GUI mode");

                Application.EnableVisualStyles();

                Application.SetCompatibleTextRenderingDefault(false);

                Application.Run(new Form1());
            }
            else if (mode == "console")
            {

                //Get a pointer to the forground window.  The idea here is that
                //IF the user is starting our application from an existing console
                //shell, that shell will be the uppermost window.  We'll get it
                //and attach to it
                IntPtr ptr = GetForegroundWindow();

                int  u;

                GetWindowThreadProcessId(ptr, out u);

                Process process = Process.GetProcessById(u);

                if (process.ProcessName == "cmd" )    //Is the uppermost window a cmd process?
                {
                    AttachConsole(process.Id);

                    //we have a console to attach to ..
                    Console.WriteLine("hello. It looks like you started me from an existing console.");
                }
                else
                {
                    //no console AND we're in console mode ... create a new console.

                    AllocConsole();

                    Console.WriteLine(@"hello. It looks like you double clicked me to start
                   AND you want console mode.  Here's a new console.");
                    Console.WriteLine("press any key to continue ...");
                    Console.ReadLine();       
                }

                FreeConsole();
            }
        }
    }
}
76
ответ дан Community 24 November 2019 в 09:51
поделиться

Самый легкий путь состоит в том, чтобы запустить приложение WinForms, перейдите к настройкам и измените тип на консольное приложение.

18
ответ дан ICR 24 November 2019 в 09:51
поделиться

Правовая оговорка

Существует способ достигнуть этого, которое довольно просто, но я не предположил бы, что это - хороший подход для приложения, которое Вы собираетесь позволить другим людям видеть. Но если бы у Вас был некоторый разработчик, то должен показать консоль и формы окон одновременно, она может быть сделана довольно легко.

Этот метод также поддерживает показ только Консоль, но не поддерживает показ, только Windows Form - т.е. Консоль будут всегда показывать. Можно только взаимодействовать (т.е. получить данные - Console.ReadLine(), Console.Read()) с консолью, если Вы не показываете формы окон; вывод к Консоли - Console.WriteLine() - работает в обоих режимах.

Это обеспечивается, как; никакие гарантии это не сделает чего-то ужасного позже, но оно действительно работает.

шаги Проекта

Начинают со стандарта Консольное приложение .

Mark Main, метод как [STAThread]

Добавляет ссылку в Вашем проекте к [1 124] Система. Windows. Формы

Добавляют Windows Form к Вашему проекту.

Добавляют, что стандартный Windows запускает код к Вашему Main метод:

Конечный результат

у Вас будет приложение, которое показывает Консоль и дополнительно формы окон.

пример кода

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ConsoleApplication9 {
    class Program {

        [STAThread]
        static void Main(string[] args) {

            if (args.Length > 0 && args[0] == "console") {
                Console.WriteLine("Hello world!");
                Console.ReadLine();
            }
            else {
                Application.EnableVisualStyles(); 
                Application.SetCompatibleTextRenderingDefault(false); 
                Application.Run(new Form1());
            }
        }
    }
}

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ConsoleApplication9 {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }

        private void Form1_Click(object sender, EventArgs e) {
            Console.WriteLine("Clicked");
        }
    }
}
13
ответ дан Sam Meldrum 24 November 2019 в 09:51
поделиться

Проверьте этот исходный код. Весь прокомментированный код †“раньше создавал консоль в Приложении Windows. Непрокомментированный †“для сокрытия консоли в консольном приложении. От здесь . (Ранее здесь .) Проект reg2run.

// Copyright (C) 2005-2015 Alexander Batishchev (abatishchev at gmail.com)

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;

namespace Reg2Run
{
    static class ManualConsole
    {
        #region DllImport
        /*
        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool AllocConsole();
        */

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CloseHandle(IntPtr handle);

        /*
        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        private static extern IntPtr CreateFile([MarshalAs(UnmanagedType.LPStr)]string fileName, [MarshalAs(UnmanagedType.I4)]int desiredAccess, [MarshalAs(UnmanagedType.I4)]int shareMode, IntPtr securityAttributes, [MarshalAs(UnmanagedType.I4)]int creationDisposition, [MarshalAs(UnmanagedType.I4)]int flagsAndAttributes, IntPtr templateFile);
        */

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool FreeConsole();

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        private static extern IntPtr GetStdHandle([MarshalAs(UnmanagedType.I4)]int nStdHandle);

        /*
        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool SetStdHandle(int nStdHandle, IntPtr handle);
        */
        #endregion

        #region Methods
        /*
        public static void Create()
        {
            var ptr = GetStdHandle(-11);
            if (!AllocConsole())
            {
                throw new Win32Exception("AllocConsole");
            }
            ptr = CreateFile("CONOUT$", 0x40000000, 2, IntPtr.Zero, 3, 0, IntPtr.Zero);
            if (!SetStdHandle(-11, ptr))
            {
                throw new Win32Exception("SetStdHandle");
            }
            var newOut = new StreamWriter(Console.OpenStandardOutput());
            newOut.AutoFlush = true;
            Console.SetOut(newOut);
            Console.SetError(newOut);
        }
        */

        public static void Hide()
        {
            var ptr = GetStdHandle(-11);
            if (!CloseHandle(ptr))
            {
                throw new Win32Exception();
            }
            ptr = IntPtr.Zero;
            if (!FreeConsole())
            {
                throw new Win32Exception();
            }
        }
        #endregion
    }
}
3
ответ дан 7vujy0f0hy 24 November 2019 в 09:51
поделиться

На самом деле AllocConsole с SetStdHandle в приложении GUI мог бы быть более безопасным подходом. Проблема с "консолью, угоняющей" уже упомянутый, состоит в том, что консоль не могла бы быть активным окном вообще, (особенно рассмотрение притока новых менеджеров окон в Vista/Windows 7) среди прочего.

1
ответ дан EFraim 24 November 2019 в 09:51
поделиться

В wind32 приложения консольного режима являются совершенно другим зверем из обычных получающих очередь сообщений приложений. Они объявляются и компилируют по-другому. Вы могли бы создать приложение, которое имеет и консольную часть и нормальное окно, и скройтесь один или другой. Но подозреваемый, Вы найдете все это немного большим количеством работы, чем Вы, думал.

0
ответ дан Joe Soul-bringer 24 November 2019 в 09:51
поделиться

Согласно кавычке Jeffrey Knight выше, как только я сталкиваюсь с ситуациями, где мне нужны вызовы API, чтобы сделать что-то, я склонен останавливаться и спрашивать меня, "я сверхусложняю вещи?".

, Если то, что требуется, должно иметь некоторый код и выполнять его в режиме Windows GUI или Консольном режиме, считать перемещение кода используемым в обоих режимах прочь к библиотеке DLL кода и затем наличию приложения Windows Forms, которое использует тот DLL и Консольное приложение, которое использует тот DLL (т.е. если в Visual Studio у Вас теперь есть решение с тремя проектами: библиотека с объемом кода, GUI только с кодом Форм Победы и Консоли только с Вашим консольным кодом.)

0
ответ дан 24 November 2019 в 09:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: