Подавить командное окно из запущенного приложения командной строки с .NET - PullRequest
4 голосов
/ 06 февраля 2010

У меня есть модуль, который должен запустить небольшую программу командной строки .Net для проверки обновлений. Все работает отлично, однако у меня возникают проблемы с отображением вывода командной строки.

Приложение имеет собственную форму Windows, которая появляется при обнаружении обновления. Обновление должно выполняться как отдельное приложение из-за того, что оно требует контекста выполнения, отличного от DLL, из которой оно запускается.

string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\" + AUTO_UPDATE_EXENAME;

updater.StartInfo.FileName = path;
updater.StartInfo.Arguments = AUTO_UPDATE_PARAMETERS;
updater.StartInfo.CreateNoWindow = false;
updater.StartInfo.UseShellExecute = false;
updater.StartInfo.RedirectStandardOutput = true;
updater.StartInfo.WorkingDirectory = path;

updater.Start();

Я перепробовал большинство всех рабочих комбинаций CreateNoWindow, UseShellExecute и RedirectStandardOutput, и каждая из них приводила к появлению этого раздражающего черного ящика. Приложение выполняет запись в стандартный вывод, но я использую его только для отладки, и пользователь не должен видеть текст, который оно генерирует.

Предположительно CreateNoWindow и / или RedirectStandardOutput должны предотвращать всплывающее окно, но не имеет значения, как я устанавливаю эти переменные.

Ответы [ 3 ]

5 голосов
/ 06 февраля 2010

Установите приложение командной строки на Winforms Application, но не открывайте форму во время его выполнения, как вы обычно это делаете.

3 голосов
/ 06 февраля 2010

Вы можете скрыть окно при запуске следующим образом:

using System.Runtime.InteropServices;

namespace MyConsoleApp {    
    class Program    {        

        [DllImport("user32.dll")]        
        public static extern IntPtr FindWindow(string lpClassName,
                                               string lpWindowName);   

        [DllImport("user32.dll")]       
        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        [STAThread()]
        static void Main(string[] args)        
        {          
            Console.Title = "MyConsoleApp";

            if (args.StartWith("-w"))            
            {                   
                // hide the console window                    
                setConsoleWindowVisibility(false, Console.Title);                   
                // open your form                    
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);                    
                Application.Run( new frmMain() );           
            }           
            // else don't do anything as the console window opens by default    
        }        

        public static void setConsoleWindowVisibility(bool visible, string title)       
        {             
            //Sometimes System.Windows.Forms.Application.ExecutablePath works  
            // for the caption depending on the system you are running under.           
            IntPtr hWnd = FindWindow(null, title); 

            if (hWnd != IntPtr.Zero)            
            {               
                if (!visible)                   
                    //Hide the window                    
                    ShowWindow(hWnd, 0); // 0 = SW_HIDE                
                else                   
                     //Show window again                    
                    ShowWindow(hWnd, 1); //1 = SW_SHOWNORMA           
             }        
        }
    }
}

http://social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/ea8b0fd5-a660-46f9-9dcb-d525cc22dcbd

0 голосов
/ 06 февраля 2010

Вот пример кода, который запрашивает MAC на активном соединении, это консольное приложение, нет необходимости делать это формой Windows ...

    public class TestARP
    {
        private StringBuilder sbRedirectedOutput = new StringBuilder();
        public string OutputData
        {
            get { return this.sbRedirectedOutput.ToString(); }
        }

        // Asynchronous!
        public void Run()
        {
            System.Diagnostics.ProcessStartInfo ps = new System.Diagnostics.ProcessStartInfo();
            ps.FileName = "arp";
            ps.ErrorDialog = false;
            ps.Arguments = "-a";
            ps.CreateNoWindow = true; // comment this out
            ps.UseShellExecute = false; // true
            ps.RedirectStandardOutput = true; // false
            ps.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; // comment this out

            using (System.Diagnostics.Process proc = new System.Diagnostics.Process())
            {
                proc.StartInfo = ps;
                proc.Exited += new EventHandler(proc_Exited);
                proc.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(proc_OutputDataReceived);
                proc.Start();
                proc.WaitForExit();
                proc.BeginOutputReadLine(); // Comment this out
            }
        }

        void proc_Exited(object sender, EventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("proc_Exited: Process Ended");
        }

        void proc_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
        {
            if (e.Data != null) this.sbRedirectedOutput.Append(e.Data + Environment.NewLine);
        }
    }

Теперь посмотрите на метод Run, который находится в асинхронном режиме и работает как одно консольное окно - на самом деле обычное консольное приложение без лишних всплывающих окон, обратите внимание на комментарии, если вы хотите изменить их. Строки, это становится синхронным процессом шелла, очень быстро, вы заметите, что эта консоль создаст другое окно с выводом команды arp. Поскольку он находится в асинхронном режиме, выходные данные перенаправляются в обработчик событий, который вставляет данные в экземпляр StringBuilder для дальнейшей обработки ...

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...