代码之家  ›  专栏  ›  技术社区  ›  Tom Corelis

使用.NET从已启动的命令行应用程序中抑制命令窗口

  •  4
  • Tom Corelis  · 技术社区  · 15 年前

    我有一个模块,需要运行一个小的.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 它们中的每一个都会导致令人讨厌的黑匣子出现。应用程序确实会写入stdout,但我只将其用于调试,用户不应该真正看到它生成的文本。

    据推测 CreateNoWindow 重定向标准输出 应该可以防止框弹出,但不管我如何设置这些变量,它都可以。

    3 回复  |  直到 15 年前
        1
  •  5
  •   Robert Harvey    15 年前

    将命令行应用程序设置为Winforms应用程序,但不要像通常那样在窗体执行时打开窗体。

        2
  •  3
  •   Robert Harvey    15 年前

    启动时可以按如下方式隐藏窗口:

    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

        3
  •  0
  •   t0mm13b    15 年前

    下面是一个在活动连接上查询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 实例进行进一步处理。。。

    希望这有帮助, 汤姆。