Подтвердить что ты не робот

Используя AttachConsole, пользователь должен нажать enter, чтобы получить стандартную командную строку

У меня есть progaram, который можно запустить как в winform, так и из командной строки. Если он вызывается из командной строки, я вызываю AttachConsole (-1) для присоединения к родительской консоли.

Однако после завершения моей программы пользователь должен нажать enter, чтобы вернуть стандартную командную строку ( "c: \ > " ). есть ли способ избежать этой необходимости?

Спасибо. Я мог бы обернуть его в cmd файл, чтобы избежать этой проблемы, но я хотел бы сделать это из моего exe.

4b9b3361

Ответ 1

Попробуйте добавить эту строку непосредственно перед выходом из exe...

System.Windows.Forms.SendKeys.SendWait("{ENTER}");

Немного взлома, но лучшее, что я мог найти, когда столкнулся с этой проблемой.

Ответ 2

Подход Rob L несколько опасен, так как он отправит Enter в активное окно. Лучший подход заключается в фактическом отправке Enter в правильный процесс (консоль).

вот как

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

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

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

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

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

        [DllImport("User32.Dll", EntryPoint = "PostMessageA")]
        internal static extern bool PostMessage(IntPtr hWnd, uint msg, int wParam, int lParam);

        internal const int VK_RETURN = 0x0D;
        internal const int WM_KEYDOWN = 0x100;
    }

- чик -

            bool attached = false;

            // Get uppermost window process
            IntPtr ptr = NativeMethods.GetForegroundWindow();
            int u;
            NativeMethods.GetWindowThreadProcessId(ptr, out u);
            Process process = Process.GetProcessById(u);

            if (string.Compare(process.ProcessName, "cmd", StringComparison.InvariantCultureIgnoreCase) == 0)
            {
                // attach to the current active console
                NativeMethods.AttachConsole(process.Id);
                attached = true;
            }
            else
            {
                // create new console
                NativeMethods.AllocConsole();
            }

            Console.Write("your output");

            NativeMethods.FreeConsole();

            if (attached)
            {
                var hWnd = process.MainWindowHandle;
                NativeMethods.PostMessage(hWnd, NativeMethods.WM_KEYDOWN, NativeMethods.VK_RETURN, 0);
            }

Это решение построено на коде, который находится здесь:

http://www.jankowskimichal.pl/en/2011/12/wpf-hybrid-application-with-parameters/

Ответ 3

Вот самый безопасный хак, который решает проблему ввода Enter, независимо от того, находится ли консольное окно на переднем плане, фон или сведено к минимуму. Вы даже можете запустить его в нескольких консольных окнах.

using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace WindowsAndConsoleApp
{
  static class Program
  {
    const uint WM_CHAR = 0x0102;
    const int VK_ENTER = 0x0D;

    [DllImport("kernel32.dll")]
    static extern bool AttachConsole(int dwProcessId);
    private const int ATTACH_PARENT_PROCESS = -1;

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

    [DllImport("kernel32.dll")]
    static extern IntPtr GetConsoleWindow();

    [DllImport("user32.dll")]
    static extern int SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);

    [STAThread]
    static void Main(string[] args)
    {
        if (args.Length > 0)
        {
            // Do this first.
            AttachConsole(ATTACH_PARENT_PROCESS);

            Console.Title = "Console Window - Enter Key Test";
            Console.WriteLine("Getting the handle of the currently executing console window...");
            IntPtr cw = GetConsoleWindow();
            Console.WriteLine($"Console handle: {cw.ToInt32()}");
            Console.WriteLine("\nPut some windows in from of this one...");
            Thread.Sleep(5000);
            Console.WriteLine("Take your time...");
            Thread.Sleep(5000);
            Console.WriteLine("Sending the Enter key now...");

            // Send the Enter key to the console window no matter where it is.
            SendMessage(cw, WM_CHAR, (IntPtr)VK_ENTER, IntPtr.Zero);

            // Do this last.
            FreeConsole();
        }
        else
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }
    }
  }
}

Ответ 4

Хорошо, у меня нет решения, но похоже, потому что cmd.exe не ждет в запущенном процессе, тогда как с обычным консольным приложением cmd.exe ждет, пока приложение не выйдет. Я не знаю, что делает cmd.exe решает подождать или нет в приложении, обычные приложения Windows Forms только что начались, и cmd.exe не дожидался его выхода. Возможно, этот намек вызывает кого-то! Я буду копать немного глубже в среднем.

Wout

Ответ 5

Попробуйте вызвать функцию FreeConsole до выхода из исполняемого файла.

Ответ 6

Это было самым простым решением для меня:

myapp.exe [params] | ECHO.